Asp.net core Asp核心UsePathBase:如何处理AJAX调用?

Asp.net core Asp核心UsePathBase:如何处理AJAX调用?,asp.net-core,middleware,Asp.net Core,Middleware,我想在相同的VPS上托管两个版本的ASP核心网站,每个提供的环境一个(登台和测试)。我希望两个网站都可以从相同URL的子文件夹访问: 在阅读了大量内容后,我发现了以下Github问题: 这个技巧对AJAX调用有效,但是它会崩溃:事实上,JavaScript调用并不知道这个新路径(BUG?)。所有请求都被发送到根基本路径(忽略/Staging或/Test) 我使用一个中间件将AJAX调用重定向到正确的路径,部分解决了这个问题。它适用于GET请求,但对于具有主体的POST请求显然失败 请注意

我想在相同的VPS上托管两个版本的ASP核心网站,每个提供的环境一个(登台和测试)。我希望两个网站都可以从相同URL的子文件夹访问:

在阅读了大量内容后,我发现了以下Github问题:

这个技巧对AJAX调用有效,但是它会崩溃:事实上,JavaScript调用并不知道这个新路径(BUG?)。所有请求都被发送到根基本路径(忽略
/Staging
/Test

我使用一个中间件将AJAX调用重定向到正确的路径,部分解决了这个问题。它适用于GET请求,但对于具有主体的POST请求显然失败

请注意,如果我们不重定向,只更改中间件中的原始PathBase请求,如果API调用需要任何身份验证架构,它将抛出401错误:原始PathBase是根
/
,其中响应具有不同的路径基,即
/Staging
,然后,标头中的cookie阻止此跨路径基本请求/响应

有人能告诉我,为了满足我的需求,推荐的做法是什么吗?

Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env
{
    app.UsePathBase($"/{env.EnvironmentName}");
    ...
}
我的中间件:

public async Task Invoke(HttpContext context)
{
    if (context.Request.Headers[RequestedWithHeader] == XmlHttpRequest)
    {
        if (string.IsNullOrEmpty(context.Request.PathBase))
        {
            if (context.Request.Method == HttpMethod.Post.Method)
            {

                // Do what ?
            }
            else
            {
                //Get request : set environement name + original path + original query string
                context.Response.Redirect(context.Request.Path.ToString().Insert(0, "/" + _env.EnvironmentName) + context.Request.QueryString);
                return;
            }
        }
    }
}

当然,客户端代码将无法根据当前请求的活动路径库自动更改其代码。JavaScript代码(通常)是静态内容,因此除非您实际动态重写代码,否则它无法更新嵌入其中的URL

您可以从当前请求的URL确定基本路径,但这是一个相当脆弱的解决方案,因为您需要找到一个无论您在应用程序中的何处都能工作的逻辑。因此,不建议这样做

总体问题是,在客户端,没有路径库(甚至没有环境)的概念。因此,您必须将这些知识从服务器转移到客户端。就像使用路径库中间件为服务器端代码设置路径库一样,您需要一些服务器端代码将路径库传递给客户端代码

我个人所做的只是在应用程序布局中配置API的根路径。因此,我的
\u Layout.cshtml
包含以下行:

<body data-api="@Url.Content("~/api/")">

这样,我就可以使用JavaScript中的
document.body.dataset.API
检索API的根路径。我的AJAX调用都会被调用,因此它们尊重这个值。这样,我可以在任何路径上托管站点,AJAX调用也将使用正确的路径


您也可以使用
“~”
作为内容路径,仅引用应用程序的根目录。如果您愿意的话,您也可以在
块内的JavaScript变量中公开此值。

好吧,在我得到您的答案之前,我按照您的建议转向完整的“前端解决方案”。但是我从URL(window.location.pathname)中提取了ENV名称,并设置了一个全局javascript变量,将其连接到所有URL AJAX调用中。这不太好,因为我不得不继续打我所有的电话,但它是有效的。谢谢这就是我所说的脆弱解决方案。您当然可以尝试解析客户端上的当前URL,但这肯定会更加复杂,并且在边缘情况下可能会导致问题。此外,您还可以有效地复制路径基逻辑。这就是我建议将根路径传递给客户端的原因。