跨域问题每次请求的sessionId不同问题

本文介绍了解决跨域资源共享(CORS)导致的Session无法正常传递的问题。通过调整Access-Control-Allow-Origin和Access-Control-Allow-Credentials设置,并在前端启用withCredentials选项,实现了跨域请求中Session的有效管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在开发项目的时候对于用户信息,验证码之类的信息,我的逻辑是将其保存在session中,当验证码比对或者后面需要用到用户信息的可以直接从session中获取值。今天在登录的时候验证码每次怎么登录怎么不成功,后台能得到前台的传值,但在后台获取session的时候取到的值为null,发现原来每次请求过来产生的session的sessionId都不一样。在以前使用前端代理没有问题,后来使用后台进行

在这里使用的是CORS进行跨域

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS还是存在一些限制,如下图所示
这里写图片描述

/**
     * 设置跨域响应header
     * @param res
     */
    public static void setCorsHeader(HttpServletResponse res,String domain){
        res.setHeader("Access-Control-Allow-Origin", domain);
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");//允许跨域的请求方式
        res.setHeader("Access-Control-Max-Age", "3600");//预检请求的间隔时间
        res.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, Access-Token");//允许跨域请求携带的请求头
        res.setHeader("Access-Control-Allow-Credentials","true");//若要返回cookie、携带seesion等信息则将此项设置我true
    }

这里的domain是在properties文件定义的


#跨域请求domain,这里设为这个固定的地址不成功
#its.cors.domain=http://127.0.0.1:8084
its.cors.domain=*

从上面的配置Header看出虽然设置了

res.setHeader("Access-Control-Allow-Credentials","true");//若要返回cookie、携带seesion等信息则将此项设置我true

但是每次请求的sessionId都不同,后来发现

Access-Control-Allow-Credentialstrue的时候。   Access-Control-Allow-Origin"的值不能为*。

所以把跨域设置改为

/**
     * 设置跨域响应header
     * @param res
     */
    public static void setCorsHeader(HttpServletResponse res,HttpServletRequest request ){
        res.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");//允许跨域的请求方式
        res.setHeader("Access-Control-Max-Age", "3600");//预检请求的间隔时间
        res.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token,Access-Control-Allow-Headers");//允许跨域请求携带的请求头
        res.setHeader("Access-Control-Allow-Credentials","true");//若要返回cookie、携带seesion等信息则将此项设置我true
    }

这样就不用每次不同的地址请求都能够动态的获取,而不用定死一个,同时Access-Control-Allow-Headers设为* 则会报错如下

Failed to load http://192.168.0.222:8084/dm/kanban/carusecount?param=%7B%22areaId%22%3A-1%2C%22startTime%22%3A%222018-08-20+10%3A12%3A00%22%2C%22endTime%22%3A%222018-08-31+11%3A00%3A00%22%2C%22countType%22%3A1%2C%22sum%22%3A0%7D: Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

另外前台的ajax也要做更改

JQuery
$.ajax({
url:url,
//加上这句话
xhrFields: {
    withCredentials: true
},
crossDomain: true,

success:function(result){
    alert("test");
},
error:function(){
}
});

Fetch

设置 credentials: “include”

getData: function (v,  callback, errorCallBack) {
    let url = URL + '/list?version='+v;
    fetch(url, {
        method: 'GET',
        credentials: "include"
    }).then((response)=>response.json())
        .then((responseJsonData)=> {
            callback && callback(responseJsonData);
        }).catch((error)=> {     
        });
},

Angular

设置{‘withCredentials’:true}

function get($scope,$http){
 $http.post(url,{v1:'name_eu'},{'withCredentials':true}).success(function(data){ $scope.var= data; }); }

至此,问题得到解决

在使用 `$.ajax` 发起 **请求** 时,要保持 **Session 会话状态**(即前后端之间能识别同一个用户),需要前后端都进行一些特定配置。否则,浏览器出于安全策略限制,默认会发送或保留 Cookie,导致 Session 无法维持。 --- ### ✅ 前端配置:启用携带 Cookie 你需要在 `$.ajax` 请求中设置: ```javascript $.ajax({ url: 'https://api.example.com/login', type: 'POST', xhrFields: { withCredentials: true // 允许携带 cookie }, crossDomain: true, success: function(data) { console.log('登录成功'); } }); ``` #### 关键参数说明: - `withCredentials: true`:允许请求携带 Cookie; - `crossDomain: true`:显式声明这是一个请求; - 如果你使用了 `dataType: 'json'` 或其他类型,请确保后端返回的响应头也正确设置。 --- ### ✅ 后端配置:允许并设置 Cookie 后端必须设置以下 HTTP 响应头来允许前端访问,并且允许 Cookie 被携带。 #### 示例(Node.js + Express): ```js const express = require('express'); const session = require('express-session'); const cors = require('cors'); const app = express(); app.use(cors({ origin: 'https://your-frontend-domain.com', // 允许的源 credentials: true // 允许携带凭证(Cookie) })); app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, cookie: { httpOnly: true, secure: false, // 开发环境设为 false;生产建议启用 HTTPS + secure: true sameSite: 'none' // 如果是请求,需设置 sameSite: 'none' } })); app.post('/login', (req, res) => { req.session.user = { id: 1, name: 'Alice' }; res.send('Logged in'); }); app.listen(3000); ``` #### 必须设置的响应头: ```http Access-Control-Allow-Origin: https://your-frontend-domain.com Access-Control-Allow-Credentials: true Set-Cookie: connect.sid=xxx; Path=/; HttpOnly; SameSite=None ``` > ⚠️ 注意: > - `Access-Control-Allow-Origin` **能是** `*`,必须指定具体名; > - `SameSite=None` 需配合 `Secure` 使用(即启用 HTTPS); > - 如果是开发环境,可以先启用 `Secure`。 --- ### ✅ 浏览器限制和注意事项 | 条件 | 是否影响 Session | |------|------------------| | 使用隐私浏览模式 | Cookie 持久,每次刷新可能丢失 Session | | 禁用第三方 Cookie | 某些浏览器(如 Safari)默认阻止 Cookie | | 清除浏览器缓存 | 删除了 Cookie,Session 也会失效 | --- ### ✅ 完整流程图解 ``` 前端发起 $.ajax({ withCredentials: true }) ↓ CORS 请求到达后端 ↓ 后端设置 Set-Cookie 并允许 Access-Control-Allow-Credentials ↓ 浏览器保存 Cookie(如果符合规则) ↓ 下次请求自动携带 Cookie(Session ID) ↓ 后端识别 Session,保持登录状态 ``` --- ### ✅ 总结 | 步骤 | 内容 | |------|------| | 前端 | 设置 `withCredentials: true` 和 `crossDomain: true` | | 后端 | 设置 CORS 允许来源 + `credentials: true` + 正确设置 Cookie 属性 | | 协议 | 前后端协议、名、端口一致或正确处理 | | Cookie | 设置 `SameSite=None; Secure`(生产环境) | ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值