浏览器同源策略与跨域

140 阅读2分钟

一.什么是同源策略

同源策略是浏览器的重要功能

同源定义:

协议、端口、主机名(域名或IP) 完全一致的两个URL(俗称网址)被称为同源

同源用途:

不同源的网页,不能共享数据/偷数据

疑问:

为什么 www.baidu.com 和 baidu.com 不是同源 因为这两个域名理论上可能属于不同的公司(如建站平台)

Tips:同源策略,目的是为了保证用户的数据安全 而如果一个公司有两个域名并且想共享数据那么就得通过跨域突破同源策略

二.如何进行跨域

  1. CORS

(1)步骤:

简单请求: 假设 b.com:9090 想把 GET /data 共享给 a.com:8080

  1. /data 在响应头设置 Access-Control-Allow-Origin: a.com:8080
  2. 没了

复杂请求(MDN)假设 a.com:8888 想把 POST /sign_in 共享给 b.com:7777

  1. a.com 后端需要响应 OPTIONS 请求,细节见 MDN
  2. a.com 后端需要响应 POST 请求,细节见 MDN 总之:CORS 是后端的活儿

2.CORS本质

简单请求

A 通过响应头告诉浏览器,我愿意共享给 B

复杂请求

为了防止 POST/PUT/PATCH + JSON + Cookie 请求对数据造成影响 浏览器会先发 OPTIONS 请求,问 A 接不接受 POST/PUT/PATCH 如果接受,浏览器才会发真正的请求 比如 post 请求的功能是打款给他人

2 JSONP

步骤

假设 b.com:9090 想把 GET /data 共享给 a.com:8080

  1. a.com 提前放置一个回调,把回调名告诉 b.com
  2. a.com 通过 script 标签来请求 b.com:9090/data
  3. b.com 后端改造 /data,把 JSON 变成 JSONP

缺点

script 只能发 get 请求 无法定向分享(可以用 referrer 实现定向) 这是后端的活儿

JSONP 的本质

取巧

由于 script 标签不受同源策略约束,可以请求任意 JS 所以后端把数据直接放在 JS 里了 对回调的使用是 JSONP 的点睛之笔 与 JSON毫无关系关系

3 反向代理 一般通过 nginx / node.js 配置实现用反向代理跨域

步骤

假设 b.com:9090 想把 GET /data 共享给 a.com:8080

  1. a.com 后端提供一个 /data(Nginx 配置如右)
  2. a.com 前端通过 AJAX 访问 a.com/data
  3. a.com/data 向 b.com/data 发请求,得到响应之后给 a.com 的前端 缺点 这是后端的活儿

总结以上三种方式皆能实现跨域但都需要后端来做(除JSONP有部分前端参与)