Übersicht über Single-Page-Webanwendung (SPA) in ASP.NET Core

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Warnung

Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Visual Studio bietet Projektvorlagen zum Erstellen von Einzelseiten-Apps (SPAs) basierend auf JavaScript-Frameworks wie Angular, React und Vue mit einem ASP.NET Core-Back-End. Diese Vorlagen:

  • Erstellen eine Visual Studio-Projektmappe mit einem Front-End-Projekt und einem Back-End-Projekt.
  • Verwenden den Visual Studio-Projekttyp für JavaScript und TypeScript (.esproj) für das Front-End.
  • Verwenden ein ASP.NET Core-Projekt für das Back-End.

Projekte, die mit den Visual Studio-Vorlagen erstellt werden, können über die Befehlszeile unter Windows, Linux und macOS ausgeführt werden. Verwenden Sie den Befehl dotnet run --launch-profile https, um das Serverprojekt mit der App auszuführen. Das Ausführen des Serverprojekts startet automatisch den Front-End-Entwicklungsserver für JavaScript. Das https-Startprofil ist derzeit erforderlich.

Visual Studio-Tutorials

Führen Sie zunächst eines der Tutorials in der Visual Studio-Dokumentation aus:

Weitere Informationen finden Sie unter JavaScript und TypeScript in Visual Studio.

ASP.NET Core-SPA-Vorlagen

Visual Studio enthält Vorlagen zum Erstellen ASP.NET Core-Apps mit einem JavaScript- oder TypeScript-Front-End. Diese Vorlagen sind in Visual Studio 2022, Version 17.8 oder höher mit installierter Workload für ASP.NET und Webentwicklung verfügbar.

Die Visual Studio-Vorlagen zum Erstellen ASP.NET Core-Apps mit einem JavaScript- oder TypeScript-Front-End bieten die folgenden Vorteile:

  • Saubere Projekttrennung für das Front-End und das Back-End.
  • Aktuelle Informationen zu den neuesten Front-End-Framework-Versionen.
  • Integration in das neueste Befehlszeilentool für Front-End-Framework, z. B. Vite.
  • Vorlagen für JavaScript und TypeScript (nur TypeScript für Angular).
  • Umfassende JavaScript- und TypeScript-Codebearbeitung.
  • Integration von JavaScript-Buildtools in den .NET-Build.
  • Benutzeroberfläche für npm-Abhängigkeitsverwaltung.
  • Kompatibel mit Visual Studio Code-Debugging- und Startkonfiguration.
  • Ausführen von Front-End-Komponententests im Test-Explorer mithilfe von JavaScript-Testframeworks.

ASP.NET Core-SPA-Vorlagen

Frühere Versionen des .NET SDK enthielten die inzwischen Legacy-Vorlagen zum Erstellen von SPA-Apps mit ASP.NET Core. Eine Dokumentation zu diesen älteren Vorlagen finden Sie in der ASP.NET Core 7.0-Version der SPA-Übersicht sowie in den Angular- und React-Artikeln.

Architektur von Single-Page-Webanwendungsvorlagen

Die SPA-Vorlagen (Single-Page-Webanwendung) für Angular und React bieten die Möglichkeit, Angular- und React-Apps zu entwickeln, die auf einem .NET-Back-End-Server gehostet werden.

Zum Zeitpunkt der Veröffentlichung werden die Dateien der Angular- und React-App in den Ordner wwwroot kopiert und über die Middleware für statische Dateien bereitgestellt.

Anstatt HTTP 404 (Nicht gefunden) zurückzugeben, verarbeitet eine Fallbackroute unbekannte Anforderungen an das Back-End und stellt den index.html für die SPA bereit.

Während der Entwicklung wird die App für die Verwendung des Front-End-Proxys konfiguriert. React und Angular verwenden denselben Front-End-Proxy.

Beim Start der App wird die index.html-Seite im Browser geöffnet. Eine spezielle Middleware, die nur während der Entwicklung aktiviert ist:

  • Fängt die eingehenden Anforderungen ab
  • Überprüft, ob der Proxy ausgeführt wird
  • Leitet an die URL des Proxys um, sofern dieser ausgeführt wird, oder startet eine neue Instanz des Proxys
  • Gibt eine Seite an den Browser zurück, die alle paar Sekunden automatisch aktualisiert wird, bis der Proxy aktiv ist und der Browser umgeleitet wird

Diagramm des Browserproxyservers

Der Hauptvorteil von ASP.NET Core-SPA-Vorlagen:

  • Sie startet einen Proxy, wenn dieser noch nicht ausgeführt wird.
  • Richtet HTTPS ein
  • Konfiguriert einige Anforderungen, die an den Back-End-Server von ASP.NET Core umgeleitet werden sollen

Wenn der Browser eine Anforderung für einen Back-End-Endpunkt sendet, z. B. /weatherforecast in den Vorlagen, empfängt der SPA-Proxy die Anforderung und sendet sie transparent an den Server zurück. Der Server antwortet, und der SPA-Proxy sendet die Anforderung zurück an den Browser:

Diagramm des Proxyservers

Veröffentlichte Single-Page-Webanwendungen

Nach ihrer Veröffentlichung wird die SPA zu einer Sammlung von Dateien im Ordner wwwroot.

Für die App ist keine Runtimekomponente erforderlich:

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();

In der oben mit der Vorlage generierten Datei Program.cs gilt Folgendes:

  • app.UseStaticFiles ermöglicht die Bereitstellung der Dateien.
  • app.MapFallbackToFile("index.html") ermöglicht die Bereitstellung des Standarddokuments für unbekannte Anforderungen, die der Server empfängt.

Wenn die App mit dotnet publish veröffentlicht wird, stellen die folgenden Aufgaben in der Datei csproj sicher, dass npm restore und das entsprechende npm-Skript ausgeführt werden, um die Produktionsartefakte zu generieren:

  <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>

Entwickeln von Single-Page-Webanwendungen

Die Projektdatei definiert einige Eigenschaften, die das Verhalten der App während der Entwicklung steuern:

<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 steuert die URL, wenn der Server die Ausführung des SPA-Proxys erwartet. Dies ist die URL:
    • Der Server pingt den Proxy nach dem Starten, um zu ermitteln, ob er bereit ist.
    • Nach einer erfolgreichen Antwort wird der Browser umgeleitet.
  • SpaProxyLaunchCommand ist der Befehl, den der Server verwendet, um den SPA-Proxy zu starten, wenn ermittelt wurde, dass der Proxy nicht ausgeführt wird.

Das Paket Microsoft.AspNetCore.SpaProxy ist für die vorherige Logik verantwortlich, um den Proxy zu ermitteln und den Browser umzuleiten.

Die in Properties/launchSettings.json definierte Hostingstartassembly wird verwendet, um während der Entwicklung automatisch die Komponenten hinzuzufügen, die erforderlich sind, um zu ermitteln, ob der Proxy ausgeführt wird, und ihn andernfalls zu starten:

{
  "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"
      }
    }
  }
}

Setup für die Client-App

Dieses Setup ist spezifisch für das Front-End-Framework, das die App verwendet, viele Aspekte der Konfiguration sind jedoch ähnlich.

Setup für Angular

Die von der Vorlage generierte Datei ClientApp/package.json:

{
  "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": {}
}
  • Enthält Skripts, die den Angular-Entwicklungsserver starten:

  • Das prestart-Skript ruft ClientApp/aspnetcore-https.js auf, mit dem sichergestellt wird, dass das HTTPS-Zertifikat des Entwicklungsservers für den SPA-Proxyserver verfügbar ist.

  • start:windows und start:default:

    • Starten den Angular-Entwicklungsserver über ng serve
    • Stellen den Port, die Optionen für die Verwendung von HTTPS und den Pfad zum Zertifikat mit dem zugehörigen Schlüssel bereit. Die angegebene Portnummer stimmt mit der in der Datei .csproj angegebenen Portnummer überein.

Die von der Vorlage generierte Datei ClientApp/angular.json enthält Folgendes:

  • serve-Befehl.

  • Ein proxyconfig-Element in der development-Konfiguration, das angibt, dass proxy.conf.js zum Konfigurieren des Front-End-Proxys verwendet werden soll, wie im folgenden hervorgehobenen JSON-Code gezeigt:

    {
      "$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 definiert die Routen, die zurück an das Server-Back-End umgeleitet werden müssen. Die allgemeinen Optionen sind unter http-proxy-middleware für React und Angular definiert, da beide denselben Proxy verwenden.

Der folgende hervorgehobene Code aus ClientApp/proxy.conf.js verwendet Logik, die auf den Umgebungsvariablen basiert, die während der Entwicklung festgelegt wurden, um den Port zu bestimmen, an dem das Back-End ausgeführt wird:

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;

Setup für React

  • Der Abschnitt „scripts“ in der Datei package.json enthält die folgenden Skripts, mit denen die React-App während der Entwicklung gestartet wird, wie im folgenden hervorgehobenen Code gezeigt:

    {
      "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"
        ]
      }
    }
    
  • Das Skript prestart ruft Folgendes auf:

    • Das Skript aspnetcore-https.js, mit dem sichergestellt wird, dass das HTTPS-Zertifikat des Entwicklungsservers für den SPA-Proxyserver verfügbar ist
    • Das Skript aspnetcore-react.js, um die entsprechende Datei .env.development.local für die Verwendung des lokalen HTTPS-Entwicklungszertifikats einzurichten. aspnetcore-react.js konfiguriert das lokale HTTPS-Entwicklungszertifikat, indem der Datei SSL_CRT_FILE=<certificate-path> und SSL_KEY_FILE=<key-path> hinzugefügt werden.
  • Die Datei .env.development definiert den Port für den Entwicklungsserver und gibt HTTPS an.

Das Skript src/setupProxy.js konfiguriert den SPA-Proxy, um die Anforderungen an das Back-End weiterzuleiten. Die allgemeinen Optionen werden unter http-proxy-middleware definiert.

Der folgende hervorgehobene Code aus ClientApp/src/setupProxy.js verwendet Logik, die auf den Umgebungsvariablen basiert, die während der Entwicklung festgelegt wurden, um den Port zu bestimmen, an dem das Back-End ausgeführt wird:

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);
};

Unterstützte SPA-Frameworkversion in ASP.NET Core SPA-Vorlagen

Die SPA-Projektvorlagen, die mit jedem ASP.NET Core Release ausgeliefert werden, verweisen auf die neueste Version des entsprechenden SPA-Frameworks.

SPA-Frameworks haben in der Regel einen kürzeren Releasezyklus als .NET. Aufgrund der zwei verschiedenen Releasezyklen kann es vorkommen, dass die unterstützten Versionen des SPA-Frameworks und von .NET nicht mehr synchronisiert werden: Die Hauptversion des SPA-Frameworks, von der ein .NET-Hauptrelease abhängt, kann nicht mehr unterstützt werden, während die .NET-Version, mit der das SPA-Framework ausgeliefert wird, weiterhin unterstützt wird.

Die ASP.NET Core SPA-Vorlagen können in einem Patchrelease auf eine neue SPA-Frameworkversion aktualisiert werden, um die Vorlagen in einem unterstützten und sicheren Zustand zu halten.

Zusätzliche Ressourcen