Fetch API 调用导致新的 Asp.net 会话

Posted

技术标签:

【中文标题】Fetch API 调用导致新的 Asp.net 会话【英文标题】:Fetch API call causes new Asp.net session 【发布时间】:2018-12-19 20:52:26 【问题描述】:

我正在我的一个 asp.net mvc 项目中删除 jQuery,转而使用纯原版 JS。现在我已经用 Fetch API 调用替换了$.ajax POST 调用,每个调用都会在服务器上触发一个新会话。

在过去的几天里,这一直让我陷入困境,我已经将其范围缩小到具体的从使用 jQuery Ajax 到 Fetch API 的转换。我的新 Fetch API 调用在其他方面工作得很好,仍然执行所需的服务器端工作。一旦它们返回就触发一个新的服务器会话。

显然,这是一个主要问题,因为我的用户会话数据不断被重置。知道为什么会这样吗?或者任何人都知道任何解决方法,而不必恢复使用 jQuery?

我之前基于 'jQuery' 的 POST 调用:

Post(route, data) 
    $.ajax(
        type: 'POST',
        url: route,
        data: JSON.stringify(data),
        contentType: "application/json; charset=utf-8"
    ).done((result, statusText, jqXHR) => 
        return result;
    );

我基于“Fetch API”的新调用:

async Post(route, data) 
    let response = await fetch(route, 
        method: 'POST',
        headers: 
            'Accept': 'application/json',
            'Content-type': 'application/json'
        ,
        body: JSON.stringify(data)
    );
    let result = await response.json();
    return result;

在我的Global.asax.cs:

protected void Session_Start(object o, EventArgs e) 
    Debug.WriteLine("Session_Start");
    HttpContext.Current.Session.Add("__MySessionData", new MySessionDataClass());

正如我上面提到的,Fetch API 调用除了重置我的会话外非常好,我从Debug.WriteLine 调用中知道这一点。 jQuery Ajax 调用也可以正常工作,并且不会触发新会话,但是我正在尝试删除对 j​​Query 的依赖。

想法?

【问题讨论】:

两种情况下发送到服务器的cookie是否不同? @gunr2171 好问题。我没想到要检查。似乎 Asp.net 会话 cookie 是通过 jQuery Ajax 调用发送的,但它不是通过 Fetch API 调用发送的。也许我必须调整 Fetch API 调用以发送会话 cookie... @gunr2171 我刚刚调整了 Fetch API 调用以在选项中添加 credentials: 'include',因此它现在发送会话 cookie,从而解决了问题。如果您想将其作为答案,我会接受。否则,我可以自行回答问题。 【参考方案1】:

在@gunr2171 的帮助下解决了这个问题,因此请自行回答,以防其他人遇到类似问题。

事实证明,我的新 Fetch API 调用并未随请求发送当前的 Asp.net 会话 cookie,因此服务器会启动一个新的会话,认为该会话尚不存在。调整 Fetch API 调用以在选项中包含 credentials: 'include' 允许它发送当前会话 cookie,并且服务器将不再在每次调用后创建一个新的。

作为参考,我的新 Fetch API 调用现在看起来像:

async Post(route, data) 
    let response = await fetch(route, 
        method: 'POST',
        headers: 
            'Accept': 'application/json',
            'Content-type': 'application/json'
        ,
        credentials: 'include',
        body: JSON.stringify(data)
    );
    let result = await response.json();
    return result;

【讨论】:

【参考方案2】:

您没有在自定义请求中传递 ASP.NET_SessionId cookie。

您正在使用fetch。 By default 它使用omit 作为credentials。这意味着,如 MDN 页面所述:

默认情况下,fetch 不会从服务器发送或接收任何 cookie,如果站点依赖于维护用户会话(发送 cookie,凭据 init 选项),则会导致未经身份验证的请求必须设置)。

JQuery 确实发送 cookie,但只发送那些在同一个域中的。

AJAX 调用仅在您调用的 url 与调用脚本位于同一域时发送 Cookie。Source

要解决此问题,您需要告诉 fetch 发送 cookie。来自this post:

fetch('/something',  credentials: 'same-origin' ) // or 'include'

【讨论】:

以上是关于Fetch API 调用导致新的 Asp.net 会话的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.net 4 Web API 2 项目通过 HttpClient 调用 REST 服务导致异常

ASP.NET MVC 5 - jQuery AJAX 有效,Fetch API 无效

如何使用 fetch 将 FormData 从 javascript 发送到 ASP.NET Core 2.1 Web API

JS Fetch API 不适用于具有 Authorize 属性的 ASP.NET Core 2 控制器

如何在asp.net核心中从客户端调用web api方法?

ASP.NET Core API 使用 JWT 不记名令牌进行身份验证