为啥我的 .Net Core 应用程序将 .cshtml 页面上脚本标签中的 js 文件作为 react js 应用程序的一部分处理?

Posted

技术标签:

【中文标题】为啥我的 .Net Core 应用程序将 .cshtml 页面上脚本标签中的 js 文件作为 react js 应用程序的一部分处理?【英文标题】:Why is my .Net Core app processing js files in script tags on .cshtml page as part of the react js application?为什么我的 .Net Core 应用程序将 .cshtml 页面上脚本标签中的 js 文件作为 react js 应用程序的一部分处理? 【发布时间】:2022-01-11 09:50:15 【问题描述】:

我们有一个现有的 .Net Core 5 Web 应用程序,我们向其中添加了一个 reactjs 应用程序,以便开始迁移网站的某些部分以进行响应。网站的两个部分分开并和谐运行时,它工作得很好,除了......

当我们加载常规 .cshtml 页面时,.Net Core 网页 (.cshtml) 的 javascript 文件将重定向到 react 应用程序,而不是将文件加载到页面。例子: 主页是 https://mydomain-dot-com/,它是一个 .Net Core .cshtml 页面。这些 js 文件位于 .cshtml 页面的 script 标签中。

<script src="~/js/what-input.js"></script>
<script src="~/js/foundation.js"></script>
<script src="~/js/web-app.js"></script>

这些脚本中的每一个都抛出可怕的 Unexpected token 错误,通常在找不到 js 文件时抛出该错误。

   Uncaught SyntaxError: Unexpected token '<'

经过进一步探索,我们发现 ~/js/what-input.js(etc.) 实际上是导致 reactjs 应用加载的原因。

reactjs 应用程序的 url 是 https://mydomain-dot-com/clientapp 并且应该只在我们导航到该 url 并且正常工作时加载。

reactjs 应用似乎正在将所有 js 文件视为反应文件并加载反应应用。

这是 startup.cs 文件和配置,因此您可以看到 SPA 是如何实现的。

public class Startup



    public Startup(IConfiguration configuration)
    
        Configuration = configuration;
    

    public IConfiguration Configuration  get; 


    public void ConfigureServices(IServiceCollection services)
    


        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
         options =>
         
             options.LoginPath = new PathString("/account/logon");
             options.AccessDeniedPath = new PathString("/account/denied");
             options.LogoutPath = new PathString("/");
             options.Cookie.HttpOnly = true; //added 11/10/2021 for reactjs app
         );

        services.ConfigureApplicationCookie(options =>
        
            options.LoginPath = new PathString("/Account/Logon");
         
        );
        

        services.AddRazorPages().AddRazorRuntimeCompilation();
        services.AddControllersWithViews().AddRazorRuntimeCompilation();

        services.AddMemoryCache();
        services.AddAuthorization();
        services.AddControllers();


        services.Configure<AppSettings>(Configuration.GetSection(AppSettings.SectionName));
        services.AddOptions();


        services.AddSpaStaticFiles(configuration => 
            configuration.RootPath = "ClientApp/build";
        );

        services.AddCors(c =>
        
            c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
        );

    


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    
        if (env.IsEnvironment("LocalDevelopment"))
        
            app.UseDeveloperExceptionPage();
        
        else
        
            app.UseExceptionHandler("/Home/Error");

            app.UseHsts();
        
        app.UseHttpsRedirection();
        app.UseDefaultFiles();
        app.UseStaticFiles(new StaticFileOptions
        
            FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @".well-known")),
            RequestPath = new PathString("/.well-known"),
            ServeUnknownFileTypes = true // serve extensionless
   
        );

        app.UseSpaStaticFiles();

        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();


        app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

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

        );


        app.UseSpa(spa => 
            spa.Options.SourcePath = "ClientApp";
            if (env.IsEnvironment("LocalDevelopment"))
            
                spa.UseReactDevelopmentServer(npmScript: "start");
            

        );


        AppDomain.CurrentDomain.SetData("ContentRootPath", env.ContentRootPath);
        AppDomain.CurrentDomain.SetData("WebRootPath", env.WebRootPath);


    

问题是我们如何防止非reactjs javascript 文件重定向到应用程序,以使它们在.cshtml 页面上表现得像他们应该的那样?有没有办法明确区分这些关注点,让它们独立行动?

【问题讨论】:

访问“/js/what-input.js”时返回的文件/HTML是什么?我认为可能是多个UseDefaultFilesUseStaticFilesUseSpaStaticFiles 导致了问题。 @LukeVo 返回的是 react 应用的默认索引页面 您可以尝试在UseDefaultFiles() 之前或之后添加app.UseStaticFiles()(仅使用默认设置),看看会发生什么?还有你的what-input.js 文件在哪里?它在wwwroot/js 文件夹中吗?如果您向我们简要介绍一下您的文件结构,可能会有所帮助。 【参考方案1】:

我认为您需要另一个中间件来提供来自 wwwroot 的内容

app.UseStaticFiles();

示例:

app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
        
            FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @".well-known")),
            RequestPath = new PathString("/.well-known"),
            ServeUnknownFileTypes = true
        );

services.AddSpaStaticFiles();

【讨论】:

以上是关于为啥我的 .Net Core 应用程序将 .cshtml 页面上脚本标签中的 js 文件作为 react js 应用程序的一部分处理?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Edge 中调试我的 asp.net core 2.0 应用程序时显示“您需要一个新应用程序才能打开此本地主机”弹出窗口?

为啥要在 ASP.Net Core 中获取多个 IMemoryCache 实例?

为啥我的 Asp.Net Core 日志中出现“不支持 POST 请求”?

为啥我的 ASP.NET Core 3.1 控制器会自动为从视图返回的 EF Core 模型分配 ID?

为啥我的 ASP.Net Core Web API 控制器不返回 XML?

为啥我在 Asp.Net CORE 中使用 JWT 获得 401 未经授权?