javascript跨域请求如何实现_CORS是什么?

CORS是浏览器强制执行的安全机制,由后端通过响应头(如Access-Control-Allow-Origin)控制,前端无法开启或绕过;它仅决定JS能否读取响应,而非阻止请求发送。

什么是 CORS?它不是前端能“实现”的东西

CORS(Cross-Origin Resource Sharing)是浏览器强制执行的一套安全机制,本质是一组 HTTP 响应头(如 Access-Control-Allow-Origin),由后端服务器在响应中主动设置。前端发请求时无法“开启”或“绕过”CORS —— 它只决定“浏览器是否允许 JS 读取响应内容”。如果后端没配好这些头,fetchXMLHttpRequest 就会抛出 TypeError: Failed to fetch 或控制台显示 Blocked by CORS policy,但请求本身(预检或实际请求)可能已发到服务端。

为什么加了 mode: 'no-cors' 还是拿不到数据?

mode: 'no-cors' 是唯一能让浏览器不校验 CORS 的方式,但它有严格限制:只能发“简单请求”(GET/POST/HEAD,且仅允许 Content-Type: text/plainapplication/x-www-form-urlencodedmultipart/form-data),且 JS **完全无法读取响应体或状态码** —— 返回的 Response 对象是“opaque”的,response.ok 永远为 falseresponse.json() 会直接报错。它只适用于“发完就不管”的埋点、日志上报等场景。

  • 不要用它来尝试“绕过 CORS 获取数据”
  • 它不会让跨域请求变成功,只是让浏览器不拦你发请求
  • 真正需要数据交互,必须后端配合返回合法 CORS 头

前端能做的有限但关键操作

前端不能决定 CORS 是否生效,但可以避免触发不必要的预检(OPTIONS 请求),减少一次网络往返:

  • 只用 GET/POST 方法,避免 PUT/DELETE/ PATCH
  • 不手动设置危险请求头,如 AuthorizationContent-Type: application/jsonX-Requested-With
  • 如果必须传 JSON,后端需支持预检并返回 Access-Control-Allow-Headers: Content-Type
  • 需要携带 cookie 时,前后端都要配:credentials: 'include' + 后端设 Access-Control-Allow-Credentials: true + Access-Control-Allow-Origin 不能为 *(必须指定具体域名)
fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ id: 123 }),
  credentials: 'include'
})

常见错误现象和对应检查点

看到 No 'Access-Control-Allow-Origin' header is present,先别改前端代码:

立即学习“Java免费学习笔记(深入)”;

  • 打开浏览器 Network 面板,看响应 Headers 里有没有 Access-Control-Allow-Origin
  • 如果是预检失败(OPTIONS 返回 404 或无 CORS 头),说明后端没处理 OPTIONS 路由或没返回 Access-Control-Allow-Methods
  • 如果响应头有 Access-Control-Allow-Origin: * 但带了 credentials: 'include',浏览器会拒绝 —— 此时后端必须写死域名,比如 https://your-app.com
  • 本地开发时用 localhost:3000 访问 localhost:8000,端口不同即跨域,和是否同主机无关

最常被忽略的是:CORS 是浏览器的事,curl、Postman、后端调用完全不受影响 —— 所以问题一定出在响应头缺失或不匹配,而不是前端“请求写错了”。