簡體   English   中英

Angular 和 ASP.NET Core MVC: "Uncaught SyntaxError: Unexpected token '<'" for index file references when deploy

[英]Angular and ASP.NET Core MVC: "Uncaught SyntaxError: Unexpected token '<'" for index file references when deployed

我有一個使用 ASP.NET Core MVC 和 Angular UI 框架的應用程序。

我可以毫無問題地在 IIS Express 開發環境中運行該應用程序。 當我切換到 IIS Express 生產環境或部署到 IIS 主機時,無法讀取我的索引引用文件,顯示瀏覽器錯誤:

未捕獲的語法錯誤:意外的標記“<”

這些頁面看起來像是在加載索引頁面,而不是 .js 或 .css 文件。 在此處輸入圖像描述

這是底層 runtime.js 的片段,因為它應該加載到瀏覽器中,它沒有加載 index.html。

/******/ (function(modules) { // webpackBootstrap
/******/    // install a JSONP callback for chunk loading
/******/    function webpackJsonpCallback(data) {
/******/        var chunkIds = data[0];
/******/        var moreModules = data[1];
/******/        var executeModules = data[2];
/******/
/******/        // add "moreModules" to the modules object,
/******/        // then flag all "chunkIds" as loaded and fire callback
/******/        var moduleId, chunkId, i = 0, resolves = [];
/******/        for(;i < chunkIds.length; i++) {
/******/            chunkId = chunkIds[i];
/******/            if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/                resolves.push(installedChunks[chunkId][0]);
/******/            }

據我了解,這應該是命名或路徑錯誤,但我可以在瀏覽器中訪問索引文件,這些文件都在同一個文件夾中,並且沒有文件名散列。 我注意到一些文件夾結構似乎從.csproj 中排除,但這似乎不會影響文件本身。 在此處輸入圖像描述

我認為這與 startup.cs、.csproj 指令或 IIS 配置有關,但沒有更具體的錯誤,我看不出出了什么問題。

程序.cs:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SNAP
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

啟動.cs:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SNAP.Data;

namespace SNAP
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            AppData.configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();


            services.AddControllersWithViews();
            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "SNAP-UI/dist/SNAP-UI";
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

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


            app.UseRouting();

            app.UseAuthorization();

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

        
            //Cannot recognize environment?
            app.UseSpa(spa =>
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "SNAP-UI";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
        }
    }
}

.csproj:

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

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
    <TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
    <IsPackable>false</IsPackable>
    <SpaRoot>SNAP-UI\</SpaRoot>
    <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>

    <!-- Set this to true if you enable server-side prerendering -->
    <BuildServerSideRenderer>false</BuildServerSideRenderer>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="5.0.5" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.5">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
    <PackageReference Include="nb.Core" Version="6.2.3" />
    <PackageReference Include="nb.Data" Version="4.3.0" />
    <PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.19" />
  </ItemGroup>

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

  <ItemGroup>
    <None Remove="SNAP-UI\browserslist" />
    <None Remove="SNAP-UI\e2e\protractor.conf.js" />
    <None Remove="SNAP-UI\e2e\src\app.e2e-spec.ts" />
    <None Remove="SNAP-UI\e2e\src\app.po.ts" />
    <None Remove="SNAP-UI\e2e\tsconfig.e2e.json" />
    <None Remove="SNAP-UI\src\app\angular-material.module.ts" />
    <None Remove="SNAP-UI\src\app\app.server.module.ts" />
    <None Remove="SNAP-UI\src\app\core\base.service.ts" />
    <None Remove="SNAP-UI\src\app\core\deal.service.ts" />
    <None Remove="SNAP-UI\src\app\counter\counter.component.html" />
    <None Remove="SNAP-UI\src\app\counter\counter.component.spec.ts" />
    <None Remove="SNAP-UI\src\app\counter\counter.component.ts" />
    <None Remove="SNAP-UI\src\app\deals\Deal.ts" />
    <None Remove="SNAP-UI\src\app\deals\dealcalendar.component.ts" />
    <None Remove="SNAP-UI\src\app\fetch-data\fetch-data.component.html" />
    <None Remove="SNAP-UI\src\app\fetch-data\fetch-data.component.ts" />
    <None Remove="SNAP-UI\src\app\home\home.component.html" />
    <None Remove="SNAP-UI\src\app\home\home.component.ts" />
    <None Remove="SNAP-UI\src\app\kendo_ui.module.ts" />
    <None Remove="SNAP-UI\src\app\nav-menu\nav-menu.component.ts" />
    <None Remove="SNAP-UI\src\karma.conf.js" />
    <None Remove="SNAP-UI\src\tsconfig.app.json" />
    <None Remove="SNAP-UI\src\tsconfig.server.json" />
    <None Remove="SNAP-UI\src\tsconfig.spec.json" />
    <None Remove="SNAP-UI\src\tslint.json" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\SNAP.Data\SNAP.Data.csproj" />
    <ProjectReference Include="..\SNAP.Domain\SNAP.Domain.csproj" />
  </ItemGroup>

  <ItemGroup>
    <TypeScriptCompile Include="SNAP-UI\src\app\angular-material.module.ts" />
    <TypeScriptCompile Include="SNAP-UI\src\app\core\base.service.ts" />
    <TypeScriptCompile Include="SNAP-UI\src\app\core\deal.service.ts" />
    <TypeScriptCompile Include="SNAP-UI\src\app\deals\deal.ts" />
    <TypeScriptCompile Include="SNAP-UI\src\app\deals\dealcalendar.component.ts" />
    <TypeScriptCompile Include="SNAP-UI\src\app\kendo_ui.module.ts" />
    <TypeScriptCompile Include="SNAP-UI\src\app\nav-menu\nav-menu.component.ts" />
  </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 --prod --ec=false --oh=media" />
    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr --prod --ec=false --oh=media" Condition=" '$(BuildServerSideRenderer)' == 'true' " />

    <!-- Include the newly-built files in the publish output -->
    <ItemGroup>
      <DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" />
      <DistFiles Include="$(SpaRoot)node_modules\**" Condition="'$(BuildServerSideRenderer)' == 'true'" />
      <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
        <RelativePath>%(DistFiles.Identity)</RelativePath>
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
        <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
      </ResolvedFileToPublish>
    </ItemGroup>
  </Target>

</Project>

更新1:

經過進一步的 IIS 調查,該頁面似乎正在為單頁應用程序進行一些 304 重定向。 這發生在 IIS Express(生產模式)和 IIS 主機上。 服務器還為非索引組件提供文本/HTML。 我在主項目中沒有 web 配置,但它是在發布時生成的。 我已將已發布的 web.config 更新為僅指向索引頁面。 這並沒有解決問題。

web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\SNAP.dll" stdoutLogEnabled="true" stdoutLogFile="C:\source\TempLog\" hostingModel="inprocess">
        <handlerSettings>
          <handlerSetting name="debugFile" value="C:\source\TempLog\tempDebug.log" />
          <handlerSetting name="debugLevel" value="FILE,TRACE" />
        </handlerSettings>
      </aspNetCore>
    </system.webServer>
  </location>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="AddTrailingSlashRule1" stopProcessing="true">
                    <match url="(.*[^/])$" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    </conditions>
                    <action type="Redirect" url="{R:1}/" />
                </rule>
                <rule name="SPA Routes" stopProcessing="true">
                    <!-- match everything by default -->
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll">
                        <!-- unless its a file -->
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <!-- or a directory -->
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                        <!-- or is under the /api directory -->
                        <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
                        <!-- list other routes or route prefixes here if you need to handle them server side -->
                    </conditions>
                    <!-- rewrite it to /index.html -->
                    <action type="Rewrite" url="/index.html" />
                </rule>
            </rules>
        </rewrite>
        <tracing>
            <traceFailedRequests>
                <add path="*">
                    <traceAreas>
                        <add provider="ASP" verbosity="Verbose" />
                        <add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
                        <add provider="ISAPI Extension" verbosity="Verbose" />
                        <add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,FastCGI,WebSocket,ANCM,Rewrite" verbosity="Verbose" />
                    </traceAreas>
                    <failureDefinitions statusCodes="200-600" />
                </add>
            </traceFailedRequests>
        </tracing>
    </system.webServer>
</configuration>
<!--ProjectGuid: d1eca6b3-ff92-4130-9f13-9b13719c7794-->

更新 2:

經過進一步調查,我注意到 Program.cs 有 2 個興趣點。 當在 IIS Express 上以生產模式運行時,該應用程序似乎不會到達服務器端,直到該應用程序在瀏覽器中刷新。 似乎CreateHostBuilder掛在 IIS Express 生產模式下。 我使用斷點確認該應用程序似乎完全完成了 startup.cs(來自 program.cs 的唯一調用)。 如果我嘗試將斷點移過CreateHostBuilder ,我會收到此錯誤。

無法設置下一條語句。 該線程調用了無法顯示的 function。

程序.cs

namespace SNAP
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
            Console.WriteLine("Build Complete");
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

因此,就我而言,當我使用 SPA 創建項目時。 我使用下一個配置。 s

https://github.com/tematre/Site/blob/master/TemaTre.Site.Resume/Startup.cs

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseDefaultFiles()
           .UseStaticFiles()
           .UseDirectoryBrowser();

        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

所以,你沒有UseDirectoryBrowser()讓我們試試,可能對你有幫助。

還有一條評論: .UseStaticFiles() 從 wwwroot 提供文件,但可以更改。 (從屏幕截圖中我看到您的文件存儲在“distrib”文件夾中)

其他選項是使用UseSpaStaticFiles()UseSpa()

  • UseSpaStaticFiles - 在 angular 應用程序的資產文件夾中提供 static 文件,如圖像、css、js

  • UseSpa - 讓 asp.net 核心知道您要運行 angular 應用程序的目錄,在生產模式下運行時的 dist 文件夾以及在開發模式下運行 angular 應用程序的命令

有使用此方法的示例:

services.AddSpaStaticFiles(configuration =>
{
 configuration.RootPath = "ClientApp/dist";
});

app.UseSpa(spa =>
{
    // To learn more about options for serving an Angular SPA from ASP.NET Core,
    // see https://go.microsoft.com/fwlink/?linkid=864501

    spa.Options.SourcePath = "ClientApp";

    if (env.IsDevelopment())
    {
        spa.UseAngularCliServer(npmScript: "start");
    }
});

也許你不見了

     app.UseStaticFiles();
        if (!env.IsDevelopment())
        {
            app.UseSpaStaticFiles();
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM