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

问题描述 投票:0回答:3

我正在我的一个 asp.net mvc 项目中删除 jQuery,转而使用直接的普通 JS。现在我已将

$.ajax
POST 调用替换为 Fetch API 调用,每个调用都会在服务器上触发一个新会话。

在过去的几天里,这一直让我感到困惑,我已经将其范围缩小到具体从使用 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 调用也工作得很好,并且不会触发新会话,但是我正在尝试删除对 jQuery 的依赖。

想法?

javascript c# jquery asp.net-mvc fetch-api
3个回答
4
投票

您没有通过自定义请求传递

ASP.NET_SessionId
cookie。

您正在使用

fetch
默认情况下,它使用
omit
作为
credentials
。正如 MDN 页面上所述,这意味着:

默认情况下,

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

JQuery 确实发送cookie,但仅限于同一域中的cookie。

如果您调用的 URL 与调用脚本位于同一域,则 AJAX 调用仅发送 Cookie。
来源

要解决此问题,您需要告诉

fetch
发送 cookie。来自这篇文章

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

2
投票

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

事实证明,我的新 Fetch API 调用并未随请求发送当前的 Asp.net 会话 cookie,因此服务器会启动一个新会话,认为该会话尚不存在。调整 Fetch API 调用以在选项中包含

credentials: 'include'
,使其可以发送当前会话 cookie,并且服务器将不再在每次调用后创建新的 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;
}

0
投票

对于以后的任何人,从 2018 年 8 月开始,默认凭据策略已更改为同源,因此即使您在 init 对象中排除“凭据”选项,如果以下情况,您的当前会话 cookie 仍将被发送:正在向同一域发出请求。 来源

© www.soinside.com 2019 - 2024. All rights reserved.