Omówienie aplikacji jednostronicowych (SPA) w usłudze ASP.NET Core

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Program Visual Studio udostępnia szablony projektów do tworzenia aplikacji jednostronicowych (SPA) opartych na strukturach Języka JavaScript, takich jak Angular, React i Vue , które mają zaplecze platformy ASP.NET Core. Te szablony:

  • Utwórz rozwiązanie programu Visual Studio z projektem frontonu i projektem zaplecza.
  • Użyj typu projektu programu Visual Studio dla języków JavaScript i TypeScript (esproj) dla frontonu.
  • Użyj projektu ASP.NET Core dla zaplecza.

Projekty utworzone przy użyciu szablonów programu Visual Studio można uruchamiać z poziomu wiersza polecenia w systemach Windows, Linux i macOS. Aby uruchomić aplikację, użyj polecenia dotnet run --launch-profile https , aby uruchomić projekt serwera. Uruchomienie projektu serwera powoduje automatyczne uruchomienie serwera programistycznego JavaScript frontonu. Profil uruchamiania https jest obecnie wymagany.

Samouczki programu Visual Studio

Aby rozpocząć pracę, wykonaj jedną z samouczków w dokumentacji programu Visual Studio:

Aby uzyskać więcej informacji, zobacz JavaScript i TypeScript w programie Visual Studio

szablony spa ASP.NET Core

Program Visual Studio zawiera szablony do tworzenia aplikacji ASP.NET Core z frontonem javaScript lub TypeScript. Te szablony są dostępne w programie Visual Studio 2022 w wersji 17.8 lub nowszej z zainstalowanym obciążeniem ASP.NET i tworzenie aplikacji internetowych.

Szablony programu Visual Studio do kompilowania aplikacji ASP.NET Core za pomocą frontonu JavaScript lub TypeScript oferują następujące korzyści:

  • Czyszczenie separacji projektów dla frontonu i zaplecza.
  • Bądź na bieżąco z najnowszymi wersjami platformy frontonu.
  • Integracja z najnowszymi narzędziami wiersza polecenia platformy frontonu, takimi jak Vite.
  • Szablony dla języków JavaScript i TypeScript (tylko TypeScript dla platformy Angular).
  • Rozbudowane środowisko edytowania kodu w języku JavaScript i TypeScript.
  • Integrowanie narzędzi kompilacji języka JavaScript z kompilacją platformy .NET.
  • Interfejs użytkownika zarządzania zależnościami npm.
  • Zgodne z konfiguracją debugowania i uruchamiania programu Visual Studio Code.
  • Uruchamianie testów jednostkowych frontonu w Eksploratorze testów przy użyciu platform testowych JavaScript.

Starsze szablony spa ASP.NET Core

Starsze wersje zestawu .NET SDK zawierały starsze szablony do tworzenia aplikacji SPA za pomocą platformy ASP.NET Core. Aby uzyskać dokumentację dotyczącą tych starszych szablonów, zobacz artykuły ASP.NET Core 7.0 z omówieniem SPA oraz artykułami Angular i React.

Architektura szablonów aplikacji jednostronicowych

Szablony aplikacji jednostronicowej dla platformy Angular i React oferują możliwość tworzenia aplikacji Angular i React hostowanych na serwerze zaplecza platformy .NET.

W czasie publikowania pliki aplikacji Angular i React są kopiowane do wwwroot folderu i są obsługiwane za pośrednictwem oprogramowania pośredniczącego plików statycznych.

Zamiast zwracać http 404 (Nie znaleziono), trasa rezerwowa obsługuje nieznane żądania do zaplecza i służy index.html dla SPA.

Podczas programowania aplikacja jest skonfigurowana do używania serwera proxy frontonu. Platformy React i Angular używają tego samego serwera proxy frontonu.

Po uruchomieniu index.html aplikacji strona zostanie otwarta w przeglądarce. Specjalne oprogramowanie pośredniczące, które jest włączone tylko w trakcie programowania:

  • Przechwytuje żądania przychodzące.
  • Sprawdza, czy serwer proxy jest uruchomiony.
  • Przekierowuje do adresu URL serwera proxy, jeśli jest uruchomiony lub uruchamia nowe wystąpienie serwera proxy.
  • Zwraca stronę do przeglądarki, która automatycznie odświeża się co kilka sekund, dopóki serwer proxy nie zostanie uruchomiony, a przeglądarka zostanie przekierowana.

Diagram serwera proxy przeglądarki

Podstawową korzyścią zapewnia szablony spa ASP.NET Core:

  • Uruchamia serwer proxy, jeśli jeszcze nie jest uruchomiony.
  • Konfigurowanie protokołu HTTPS.
  • Konfigurowanie niektórych żądań, które mają być proxied na serwerze zaplecza ASP.NET Core.

Gdy przeglądarka wysyła żądanie dla punktu końcowego zaplecza, na przykład /weatherforecast w szablonach. Serwer proxy SPA odbiera żądanie i wysyła go z powrotem do serwera w sposób niewidoczny. Serwer odpowiada, a serwer proxy SPA wysyła żądanie z powrotem do przeglądarki:

Diagram serwera proxy

Opublikowane aplikacje jednostronicowe

Po opublikowaniu aplikacji SPA staje się kolekcją plików w folderze wwwroot .

Do obsługi aplikacji nie jest wymagany żaden składnik środowiska uruchomieniowego:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();


app.MapControllerRoute(
    name: "default",
    pattern: "{controller}/{action=Index}/{id?}");

app.MapFallbackToFile("index.html");

app.Run();

W poprzednim szablonie wygenerowany Program.cs plik:

  • app.UseStaticFiles umożliwia obsługiwanie plików.
  • app.MapFallbackToFile("index.html") włącza obsługę dokumentu domyślnego dla dowolnego nieznanego żądania odbieranego przez serwer.

Po opublikowaniu aplikacji przy użyciu polecenia dotnet publish następujące zadania w csproj pliku zapewniają, że npm restore działa i że odpowiedni skrypt npm jest uruchamiany w celu wygenerowania artefaktów produkcyjnych:

  <Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
    <!-- Ensure Node.js is installed -->
    <Exec Command="node --version" ContinueOnError="true">
      <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
    </Exec>
    <Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
    <Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
  </Target>

  <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
    <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />

    <!-- Include the newly-built files in the publish output -->
    <ItemGroup>
      <DistFiles Include="$(SpaRoot)build\**" />
      <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        <RelativePath>wwwroot\%(RecursiveDir)%(FileName)%(Extension)</RelativePath>
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
      </ResolvedFileToPublish>
    </ItemGroup>
  </Target>
</Project>

Tworzenie aplikacji jednostronicowych

Plik projektu definiuje kilka właściwości, które kontrolują zachowanie aplikacji podczas programowania:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
    <TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
    <IsPackable>false</IsPackable>
    <SpaRoot>ClientApp\</SpaRoot>
    <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
    <SpaProxyServerUrl>https://localhost:44414</SpaProxyServerUrl>
    <SpaProxyLaunchCommand>npm start</SpaProxyLaunchCommand>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.SpaProxy" Version="7.0.1" />
  </ItemGroup>

  <ItemGroup>
    <!-- Don't publish the SPA source files, but do show them in the project files list -->
    <Content Remove="$(SpaRoot)**" />
    <None Remove="$(SpaRoot)**" />
    <None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />
  </ItemGroup>

  <Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
    <!-- Ensure Node.js is installed -->
    <Exec Command="node --version" ContinueOnError="true">
      <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
    </Exec>
    <Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
    <Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
  </Target>

  <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
    <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />

    <!-- Include the newly-built files in the publish output -->
    <ItemGroup>
      <DistFiles Include="$(SpaRoot)build\**" />
      <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        <RelativePath>wwwroot\%(RecursiveDir)%(FileName)%(Extension)</RelativePath>
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
      </ResolvedFileToPublish>
    </ItemGroup>
  </Target>
</Project>
  • SpaProxyServerUrl: określa adres URL, pod którym serwer oczekuje uruchomienia serwera proxy SPA. Jest to adres URL:
    • Serwer pinguje po uruchomieniu serwera proxy, aby dowiedzieć się, czy jest gotowy.
    • Gdzie przekierowuje przeglądarkę po pomyślnej odpowiedzi.
  • SpaProxyLaunchCommand: Polecenie używane przez serwer do uruchamiania serwera proxy SPA, gdy wykryje, że serwer proxy nie jest uruchomiony.

Pakiet Microsoft.AspNetCore.SpaProxy jest odpowiedzialny za poprzednią logikę wykrywania serwera proxy i przekierowywania przeglądarki.

Zestaw uruchamiania hostingu zdefiniowany w programie Properties/launchSettings.json jest używany do automatycznego dodawania wymaganych składników podczas programowania niezbędnego do wykrywania, czy serwer proxy jest uruchomiony i uruchamia go w przeciwnym razie:

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:51783",
      "sslPort": 44329
    }
  },
  "profiles": {
    "MyReact": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:7145;http://localhost:5273",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
      }
    }
  }
}

Konfiguracja aplikacji klienckiej

Ta konfiguracja jest specyficzna dla struktury frontonu używanej przez aplikację, jednak wiele aspektów konfiguracji jest podobnych.

Konfiguracja platformy Angular

Wygenerowany ClientApp/package.json plik szablonu:

{
  "name": "myangular",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "prestart": "node aspnetcore-https",
    "start": "run-script-os",
    "start:windows": "ng serve --port 44483 --ssl --ssl-cert \"%APPDATA%\\ASP.NET\\https\\%npm_package_name%.pem\" --ssl-key \"%APPDATA%\\ASP.NET\\https\\%npm_package_name%.key\"",
    "start:default": "ng serve --port 44483 --ssl --ssl-cert \"$HOME/.aspnet/https/${npm_package_name}.pem\" --ssl-key \"$HOME/.aspnet/https/${npm_package_name}.key\"",
    "build": "ng build",
    "build:ssr": "ng run MyAngular:server:dev",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^14.1.3",
    "@angular/common": "^14.1.3",
    "@angular/compiler": "^14.1.3",
    "@angular/core": "^14.1.3",
    "@angular/forms": "^14.1.3",
    "@angular/platform-browser": "^14.1.3",
    "@angular/platform-browser-dynamic": "^14.1.3",
    "@angular/platform-server": "^14.1.3",
    "@angular/router": "^14.1.3",
    "bootstrap": "^5.2.0",
    "jquery": "^3.6.0",
    "oidc-client": "^1.11.5",
    "popper.js": "^1.16.0",
    "run-script-os": "^1.1.6",
    "rxjs": "~7.5.6",
    "tslib": "^2.4.0",
    "zone.js": "~0.11.8"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^14.1.3",
    "@angular/cli": "^14.1.3",
    "@angular/compiler-cli": "^14.1.3",
    "@types/jasmine": "~4.3.0",
    "@types/jasminewd2": "~2.0.10",
    "@types/node": "^18.7.11",
    "jasmine-core": "~4.3.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.1.1",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "^2.0.0",
    "typescript": "~4.7.4"
  },
  "overrides": {
    "autoprefixer": "10.4.5"
  },
  "optionalDependencies": {}
}
  • Zawiera skrypty uruchamiające serwer programistyczny angular:

  • Skrypt prestart wywołuje metodę ClientApp/aspnetcore-https.js, która jest odpowiedzialna za zapewnienie, że certyfikat HTTPS serwera deweloperów jest dostępny dla serwera proxy SPA.

  • start:defaultI start:windows :

    • Uruchom serwer programistyczny Angular za pomocą polecenia ng serve.
    • Podaj port, opcje użycia protokołu HTTPS oraz ścieżkę do certyfikatu i skojarzonego klucza. Numer portu podaj jest zgodny z numerem .csproj portu określonym w pliku.

Wygenerowany ClientApp/angular.json plik szablonu zawiera:

  • Polecenie serve .

  • Element proxyconfig w development konfiguracji wskazujący, że proxy.conf.js należy użyć go do skonfigurowania serwera proxy frontonu, jak pokazano w poniższym wyróżnionym wł JS.:

    {
      "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
      "version": 1,
      "newProjectRoot": "projects",
      "projects": {
        "MyAngular": {
          "projectType": "application",
          "schematics": {
            "@schematics/angular:application": {
              "strict": true
            }
          },
          "root": "",
          "sourceRoot": "src",
          "prefix": "app",
          "architect": {
            "build": {
              "builder": "@angular-devkit/build-angular:browser",
              "options": {
                "progress": false,
                "outputPath": "dist",
                "index": "src/index.html",
                "main": "src/main.ts",
                "polyfills": "src/polyfills.ts",
                "tsConfig": "tsconfig.app.json",
                "allowedCommonJsDependencies": [
                  "oidc-client"
                ],
                "assets": [
                  "src/assets"
                ],
                "styles": [
                  "node_modules/bootstrap/dist/css/bootstrap.min.css",
                  "src/styles.css"
                ],
                "scripts": []
              },
              "configurations": {
                "production": {
                  "budgets": [
                    {
                      "type": "initial",
                      "maximumWarning": "500kb",
                      "maximumError": "1mb"
                    },
                    {
                      "type": "anyComponentStyle",
                      "maximumWarning": "2kb",
                      "maximumError": "4kb"
                    }
                  ],
                  "fileReplacements": [
                    {
                      "replace": "src/environments/environment.ts",
                      "with": "src/environments/environment.prod.ts"
                    }
                  ],
                  "outputHashing": "all"
                },
                "development": {
                  "buildOptimizer": false,
                  "optimization": false,
                  "vendorChunk": true,
                  "extractLicenses": false,
                  "sourceMap": true,
                  "namedChunks": true
                }
              },
              "defaultConfiguration": "production"
            },
            "serve": {
              "builder": "@angular-devkit/build-angular:dev-server",
              "configurations": {
                "production": {
                  "browserTarget": "MyAngular:build:production"
                },
                "development": {
                  "browserTarget": "MyAngular:build:development",
                  "proxyConfig": "proxy.conf.js"
                }
              },
              "defaultConfiguration": "development"
            },
            "extract-i18n": {
              "builder": "@angular-devkit/build-angular:extract-i18n",
              "options": {
                "browserTarget": "MyAngular:build"
              }
            },
            "test": {
              "builder": "@angular-devkit/build-angular:karma",
              "options": {
                "main": "src/test.ts",
                "polyfills": "src/polyfills.ts",
                "tsConfig": "tsconfig.spec.json",
                "karmaConfig": "karma.conf.js",
                "assets": [
                  "src/assets"
                ],
                "styles": [
                  "src/styles.css"
                ],
                "scripts": []
              }
            },
            "server": {
              "builder": "@angular-devkit/build-angular:server",
              "options": {
                "outputPath": "dist-server",
                "main": "src/main.ts",
                "tsConfig": "tsconfig.server.json"
              },
              "configurations": {
                "dev": {
                  "optimization": true,
                  "outputHashing": "all",
                  "sourceMap": false,
                  "namedChunks": false,
                  "extractLicenses": true,
                  "vendorChunk": true
                },
                "production": {
                  "optimization": true,
                  "outputHashing": "all",
                  "sourceMap": false,
                  "namedChunks": false,
                  "extractLicenses": true,
                  "vendorChunk": false
                }
              }
            }
          }
        }
      },
      "defaultProject": "MyAngular"
    }
    

ClientApp/proxy.conf.js definiuje trasy, które muszą być proxied z powrotem do zaplecza serwera. Ogólny zestaw opcji jest definiowany w przypadku oprogramowania pośredniczącego http-proxy-react i angular, ponieważ oba używają tego samego serwera proxy.

Poniższy wyróżniony kod z logiki korzysta z ClientApp/proxy.conf.js logiki opartej na zmiennych środowiskowych ustawionych podczas programowania w celu określenia portu, na którym działa zaplecze:

const { env } = require('process');

const target = env.ASPNETCORE_HTTPS_PORTS ? `https://localhost:${env.ASPNETCORE_HTTPS_PORTS}` :
  env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:51951';

const PROXY_CONFIG = [
  {
    context: [
      "/weatherforecast",
   ],
    target: target,
    secure: false,
    headers: {
      Connection: 'Keep-Alive'
    }
  }
]

module.exports = PROXY_CONFIG;

Konfiguracja platformy React

  • Sekcja package.json skryptów zawiera następujące skrypty uruchamiające aplikację react podczas programowania, jak pokazano w poniższym wyróżnionym kodzie:

    {
      "name": "myreact",
      "version": "0.1.0",
      "private": true,
      "dependencies": {
        "bootstrap": "^5.2.0",
        "http-proxy-middleware": "^2.0.6",
        "jquery": "^3.6.0",
        "merge": "^2.1.1",
        "oidc-client": "^1.11.5",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "react-router-bootstrap": "^0.26.2",
        "react-router-dom": "^6.3.0",
        "react-scripts": "^5.0.1",
        "reactstrap": "^9.1.3",
        "rimraf": "^3.0.2",
        "web-vitals": "^2.1.4",
        "workbox-background-sync": "^6.5.4",
        "workbox-broadcast-update": "^6.5.4",
        "workbox-cacheable-response": "^6.5.4",
        "workbox-core": "^6.5.4",
        "workbox-expiration": "^6.5.4",
        "workbox-google-analytics": "^6.5.4",
        "workbox-navigation-preload": "^6.5.4",
        "workbox-precaching": "^6.5.4",
        "workbox-range-requests": "^6.5.4",
        "workbox-routing": "^6.5.4",
        "workbox-strategies": "^6.5.4",
        "workbox-streams": "^6.5.4"
      },
      "devDependencies": {
        "ajv": "^8.11.0",
        "cross-env": "^7.0.3",
        "eslint": "^8.22.0",
        "eslint-config-react-app": "^7.0.1",
        "eslint-plugin-flowtype": "^8.0.3",
        "eslint-plugin-import": "^2.26.0",
        "eslint-plugin-jsx-a11y": "^6.6.1",
        "eslint-plugin-react": "^7.30.1",
        "nan": "^2.16.0",
        "typescript": "^4.7.4"
      },
      "overrides": {
        "autoprefixer": "10.4.5"
      },
      "resolutions": {
        "css-what": "^5.0.1",
        "nth-check": "^3.0.1"
      },
      "scripts": {
        "prestart": "node aspnetcore-https && node aspnetcore-react",
        "start": "rimraf ./build && react-scripts start",
        "build": "react-scripts build",
        "test": "cross-env CI=true react-scripts test --env=jsdom",
        "eject": "react-scripts eject",
        "lint": "eslint ./src/"
      },
      "eslintConfig": {
        "extends": [
          "react-app"
        ]
      },
      "browserslist": {
        "production": [
          ">0.2%",
          "not dead",
          "not op_mini all"
        ],
        "development": [
          "last 1 chrome version",
          "last 1 firefox version",
          "last 1 safari version"
        ]
      }
    }
    
  • Skrypt prestart wywołuje następujące wywołania:

    • aspnetcore-https.js, który jest odpowiedzialny za zapewnienie, że certyfikat HTTPS serwera deweloperów jest dostępny dla serwera proxy SPA.
    • aspnetcore-react.js Wywołuje polecenie w celu skonfigurowania odpowiedniego .env.development.local pliku w celu użycia lokalnego certyfikatu dewelopera HTTPS. aspnetcore-react.js Konfiguruje lokalny certyfikat programowania HTTPS przez dodanie SSL_CRT_FILE=<certificate-path> i SSL_KEY_FILE=<key-path> do pliku.
  • Plik .env.development definiuje port serwera programistycznego i określa protokół HTTPS.

Konfiguruje src/setupProxy.js serwer proxy SPA do przekazywania żądań do zaplecza. Ogólny zestaw opcji jest zdefiniowany w programie http-proxy-middleware.

Poniższy wyróżniony kod w programie ClientApp/src/setupProxy.js używa logiki opartej na zmiennych środowiskowych ustawionych podczas programowania w celu określenia portu, na którym działa zaplecze:

const { createProxyMiddleware } = require('http-proxy-middleware');
const { env } = require('process');

const target = env.ASPNETCORE_HTTPS_PORTS ? `https://localhost:${env.ASPNETCORE_HTTPS_PORTS}` :
  env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:51783';

const context = [
  "/weatherforecast",
];

const onError = (err, req, resp, target) => {
    console.error(`${err.message}`);
}

module.exports = function (app) {
  const appProxy = createProxyMiddleware(context, {
    target: target,
    // Handle errors to prevent the proxy middleware from crashing when
    // the ASP NET Core webserver is unavailable
    onError: onError,
    secure: false,
    // Uncomment this line to add support for proxying websockets
    //ws: true, 
    headers: {
      Connection: 'Keep-Alive'
    }
  });

  app.use(appProxy);
};

Obsługiwana wersja struktury SPA w szablonach spa ASP.NET Core

Szablony projektu SPA dostarczane z każdym ASP.NET Core odwołania do najnowszej wersji odpowiedniej struktury SPA.

Struktury SPA zwykle mają krótszy cykl wydawania niż .NET. Ze względu na dwa różne cykle wydania, obsługiwana wersja struktury SPA i .NET może wydostać się z synchronizacji: główna wersja struktury SPA, od których zależy główna wersja platformy .NET, może wyjść z pomocy technicznej, podczas gdy platforma SPA dostarczana z programem jest nadal obsługiwana.

Szablony ASP.NET Core SPA można zaktualizować w wydaniu poprawki do nowej wersji struktury SPA, aby zachować szablony w obsługiwanym i bezpiecznym stanie.

Dodatkowe zasoby