0%

跨域&同源

同源&跨域

🔒 同源策略(Same-Origin Policy)

浏览器的安全机制,限制 JS 对不同源资源的访问。判断是否同源需满足:协议、域名、端口号相同

示例:

页面地址 资源地址 是否同源 🚨原因
http://a.com:80 http://a.com:80 完全相同
http://a.com https://a.com 协议不同
http://a.com http://b.com 域名不同
http://a.com:80 http://a.com:8080 端口不同

🚫 哪些操作会被限制?

  • JS 发起的 fetch / XMLHttpRequest 跨域请求
  • 访问 localStoragecookie 等数据
  • iframe 跨域访问父/子页面 DOM

🌐 什么是跨域?

浏览器阻止你访问不同源资源时,就发生了跨域。
非同源访问资源(如 Ajax 请求)默认会被浏览器拦截。


简单请求与复杂请求

浏览器把跨域请求分为两类:

✅ 简单请求(不会发送预检)

同时满足以下三个条件:

  1. 方法是 GETPOSTHEAD
  2. 请求头 仅限于AcceptAccept-LanguageContent-Type(值仅限于:application/x-www-form-urlencodedmultipart/form-datatext/plain
  3. 没有自定义请求头

⚠️ 复杂请求(会先发送预检 OPTIONS 请求)

只要满足以下任意一项,就属于复杂请求:

  • 方法为 PUTDELETE 等非 GET/POST/HEAD
  • 请求头中有自定义 Header(如 X-Token
  • Content-Typeapplication/json 等非简单类型
  • 使用了 XMLHttpRequest.withCredentials = true(携带 cookie)

🔁 流程:

  1. 浏览器先发 OPTIONS 请求询问服务器是否允许
  2. 服务器返回 Access-Control-Allow-* 系列响应头,表示允许
  3. 浏览器才会发起真正的请求

⛔ 若预检失败(服务器未正确设置允许跨域),正式请求不会被发送


🔁 预检请求长这样(由浏览器自动发出):

1
2
3
4
httpCopyEditOPTIONS /user HTTP/1.1
Origin: https://web.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type

服务端响应应如下:

1
2
3
4
httpCopyEditHTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://web.example.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type

✅ CORS:主流跨域解决方案

服务端返回特殊响应头,告诉浏览器“我允许你跨域访问”:

示例:

1
2
3
Access-Control-Allow-Origin: https://your-frontend.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type

通配符允许所有:

1
Access-Control-Allow-Origin: *

🧪 跨域开发常见解决方案

方式 说明
✅ CORS 服务端设置响应头(最推荐)
🌀 代理转发 本地开发用 webpack devServer 或 Nginx 转发
📜 JSONP 只支持 GET,已过时
📨 postMessage iframe/窗口间通信方案