【问题标题】:Asp Core UsePathBase : how to deal with AJAX calls?Asp Core UsePathBase:如何处理 AJAX 调用?
【发布时间】:2018-01-08 12:30:08
【问题描述】:

我想在同一个 VPS 上托管我的 ASP Core 网站的两个版本,一个用于每个提供的环境(暂存和测试)。我希望可以从同一 URL 的子文件夹访问这两个网站:

在阅读了很多之后,我发现了以下 Github 问题:https://github.com/aspnet/Hosting/issues/815

此提示有效对于 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;
            }
        }
    }
}

【问题讨论】:

    标签: asp.net-core middleware


    【解决方案1】:

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

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

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

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

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

    这样,我就可以在 JavaScript 中使用 document.body.dataset.api 检索 API 的根路径。然后我的 AJAX 调用全部进行,因此它们尊重该值。这样,我可以在任何路径上托管网站,并且 AJAX 调用也将使用正确的路径。

    您也可以只使用"~" 作为内容路径来引用应用程序的根目录。如果您愿意,也可以在 &lt;script&gt; 块内的 JavaScript 变量中公开此值。

    【讨论】:

    • 好吧,在我得到你的答案之前,我会按照你的建议转向一个完整的“前端解决方案”。但是我从 URL (window.location.pathname) 中提取了 ENV 名称,并设置了一个全局 javascript 变量,将其连接到我的所有 url AJAX 调用。这并不漂亮,因为我必须继续我的所有电话,但它有效。谢谢
    • 这就是我所说的脆弱解决方案。您当然可以尝试在客户端解析当前 URL,但这必然会更加复杂,并且可能会在极端情况下导致问题。此外,您实际上是在复制路径基础逻辑。这就是为什么我建议只将根路径传递给客户端。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 2011-03-23
    • 2021-08-21
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多