验证跨域 cookie 的坑

坑点 1:伪跨域测试 (localhost 骗局) 问题: 前后端都用 localhost,虽然端口不同 (比如 3000 和 4000),前后端都是同站点,都是 localhostsameSite: 'strict' 在这种场景不生效,因为他只限制,就是如果是不同站点的话,就不发 cookie,但是现在明显是同站点,都是 localhost,cookie 照样发,测不出跨域问题!

解决: 狠心让前后端"分手"!前端用 http://localhost:3000,后端用 http://127.0.0.1:4000,现在前后端既跨域,又是不同站点。

坑点 2:Cookie 设置被浏览器无视 (secure + sameSite 强制 CP)

问题: 后端设置了 sameSite: 'none'(允许跨域带 Cookie),但必须同时加 secure: true(只允许 HTTPS)。不加这个,浏览器直接扔了你的 Cookie!

测试环境: 谷歌浏览器允许在设置了 secure: true 的情况下,测试环境使用 http 依旧可以发送 cookie(但是仅限当前会话,浏览器一刷新 cookie 就丢了)。

解决: 后端发 Cookie 必须锁死这对组合

arduino 复制代码
res.cookie('名字', '值', {
  sameSite: 'none',
  secure: true,   // 这俩必须同时出现!
  // ...其他配置
});

坑点 3:credentials: 'include'

credentials: 'include' 的作用:

  1. 浏览器携带相关 Cookie 给后端。
  2. 浏览器保存后端送来的 Cookie,也就是说你不设置这个东西,后端给的 Cookie 前端不会保存的。

解决:

arduino 复制代码
await fetch(后端地址, {
  method: 'GET', // 或其他
  credentials: 'include' // 关键!意思是:我要存/带 Cookie!
});

坑点 4:Access-Control-Allow-Credentials

Access-Control-Allow-Credentials: true 的作用是:

允许浏览器携带 cookie,这个属性主要是告诉浏览器,你能不能带东西过来,如果我不允许,你还带,浏览器自己就会报 cors 错误。

解决:

arduino 复制代码
// 你的手动 CORS 中间件里:
res.setHeader('Access-Control-Allow-Credentials', 'true'); // 必须加这行!

如果不设置这个属性:

你前端带东西过去,后端不允许你前端带东西,那前端就报错了。

最后给出验证代码

xml 复制代码
<!-- frontend/index.html -->
<!DOCTYPE html>
<html lang="">
<meta charset="utf-8"></meta>
<head>
  <title>跨域Cookie演示</title>
</head>
<body>
<h1>跨域Cookie设置演示</h1>
<button id="requestBtn">发送跨域请求</button>
<script>
  document.getElementById('requestBtn').addEventListener('click', async () => {
    try {
      const backendUrl = 'http://127.0.0.1:4000/api/cookie'
​
      await fetch(`${backendUrl}/set`, {
        method: 'GET',
        credentials: 'include' // 保存后端送来的 cookie
      })
​
      await fetch(`${backendUrl}/get`, {
        method: 'GET',
        credentials: 'include' // 携带已有的 cookie 发送给后端
      })
​
    } catch (error) {
      console.error('发生错误:', error)
    }
  })
</script>
</body>
</html>
javascript 复制代码
const express = require('express')
const cookieParser = require('cookie-parser')
​
const app = express()
const BACKEND_PORT = 4000
​
// 关键中间件
app.use(cookieParser())
app.use(express.json())
​
// 手动CORS中间件 (替换cors库)
app.use((req, res, next) => {
  // 1. 允许任意源访问
  const origin = req.headers.origin
  if (origin) {
    res.setHeader('Access-Control-Allow-Origin', origin)
  }
​
  // 1.允许前端保存 cookie 2.允许前端传递 cookie
  res.setHeader('Access-Control-Allow-Credentials', 'true')
​
  next()
})
​
// Route 1: 设置Cookie
app.get('/api/cookie/set', (req, res) => {
  // 关键Cookie设置 (注意属性)
  res.cookie('custom_cookie', 'super_secret_value', {
    secure: true,     // 在 https 请求才会携带 cookie(sameSite: 'none',时 secure: true 要同时成立)
    sameSite: 'none',  // 必须:允许跨域访问
    path: '/',         // 整个网站可用
    maxAge: 36000000    // 过期时间
  })
​
  res.send('Cookie已设置!检查浏览器控制台的Network标签')
})
​
// Route 2: 检查Cookie是否被发回
app.get('/api/cookie/get', (req, res) => {
  console.log(req.cookies)
​
  res.send(req.cookies)
})
​
app.listen(BACKEND_PORT, () => {
  console.log(`
╔═════════════════════════════════════════╗
║  后端服务运行中                          ║
║  地址: http://localhost:${BACKEND_PORT} ║
╚═════════════════════════════════════════╝
  `)
})

总之,因为浏览器默认跨域是不会保存 cookie 的,总之为了跨域 cookie 不出问题,前端就要 credentials: 'include',后端就要 res.setHeader('Access-Control-Allow-Credentials', 'true')

当然这都是我在本地测试的环境,鬼知道谷歌浏览器的本地测试,还有其他不同浏览器有没有不同的差异,或者上线实际的生产环境,https环境,会不会有什么其他的问题,这都是有待测试的,有其他兄弟测试过,也可以跟我讲一讲。

相关推荐
用户54277848515401 分钟前
Promise :从基础原理到高级实践
前端
用户4099322502124 分钟前
Vue3条件渲染中v-if系列指令如何合理使用与规避错误?
前端·ai编程·trae
Mr_Swilder8 分钟前
2025-12-20 vue3中 eslint9+和prettier配置
前端
code_YuJun9 分钟前
脚手架开发工具——判断文件是否存在 path-exists
前端
code_YuJun10 分钟前
脚手架开发工具——root-check
前端
用户542778485154010 分钟前
XMLHttpRequest、AJAX、Fetch 与 Axios
前端
打小就很皮...17 分钟前
React 实现富文本(使用篇&Next.js)
前端·react.js·富文本·next.js
智算菩萨1 小时前
实战:高级中文自然语言处理系统的Python设计与实现
前端·javascript·easyui
远山无期1 小时前
解决Tailwind任意值滥用:规范化CSS开发体验
前端·css·eslint
用户54277848515401 小时前
Vue 3 中开发高阶组件(HOC)与 Renderless 组件
前端