CORS跨域问题求助:带凭证请求遭拦截,无目标服务器权限如何解决?
解决跨域CORS问题的可行方案及no-cors模式的影响
错误原因
你发起的请求带了credentials: 'include'(会携带cookie等凭证),但请求被重定向后,目标服务器返回的Access-Control-Allow-Origin头是通配符*——根据CORS规则,带凭证的请求不允许用通配符作为允许的源,所以浏览器拦截了响应。
可行解决办法(无法修改目标服务器的情况下)
1. 用自己的后端做代理
这是最实用的方案,因为后端之间的HTTP请求不受浏览器CORS规则限制。步骤如下:
- 在你的Express后端添加一个代理路由(以axios为例,也可以用原生https模块):
const axios = require('axios'); app.post('/api/proxy-get-user-data', async (req, res) => { try { // 向后端目标服务器发起请求 const response = await axios.post('https://devapi.madgs.ru/get-user-data', {}, { // 如果需要给目标服务器传递凭证,开启这个选项 withCredentials: true }); // 将目标服务器的响应原封不动返回给前端 res.status(response.status).json(response.data); } catch (error) { res.status(error.response?.status || 500).send(error.message); } });
- 前端修改fetch请求,指向自己的后端代理路由:
fetch('https://dev.madgs.ru/api/proxy-get-user-data', { method: 'POST', credentials: 'include' // 和自己的后端同源,这个设置完全合法 }).then(response => response.json()) .then(data => { // 这里可以正常处理用户数据了 }) .catch(error => { console.error('Error:', error); });
通过后端转发,前端和自己的服务同源,彻底绕过CORS限制,同时能正常传递凭证、获取响应数据。
2. 移除credentials: 'include'(如果不需要凭证的话)
如果你的请求不需要携带cookie或其他认证凭证,可以把credentials参数改成'same-origin'或者直接删掉,这样即使目标服务器返回Access-Control-Allow-Origin: *,浏览器也不会拦截响应。但如果必须带凭证才能获取用户数据,这个方案不可行。
关于no-cors模式的疑问
能不能用?
可以用,但完全满足不了你获取用户数据的需求,因为:
- 请求会返回一个「不透明响应」,前端无法读取响应的任何内容(调用
response.json()、response.text()都会直接报错),只能知道请求是否发送成功,但拿不到你需要的用户数据。 - 限制极多:只能使用GET/HEAD/POST方法,请求头只能是浏览器允许的「简单头」(比如Accept、Content-Type仅限
application/x-www-form-urlencoded等三种),不能自定义复杂头。
对请求和安全性的影响
- 请求方面:能把数据发出去,但拿不到结果,只适合上报日志这类不需要响应的场景,对你当前获取用户数据的场景毫无意义。
- 安全性方面:因为无法读取响应,不会把目标服务器的恶意数据暴露给前端页面,但也意味着你无法验证请求是否拿到了正确数据。浏览器对这类请求的使用场景做了严格限制,避免滥用。
额外提示:你的后端代码可以优化
你同时使用了cors中间件和手动设置CORS头,会导致响应头重复,建议删掉手动设置的那段代码,只保留cors中间件的配置即可:
// 只保留这段配置,移除下面手动设置header的app.use app.use(cors({ origin: 'https://dev.madgs.ru', methods: ['GET', 'POST'], credentials: true }));
内容的提问来源于stack exchange,提问作者Uximy
相关产品推荐
相关产品推荐

