如何跨域

43 阅读1分钟

为什么要跨域?

浏览器自带一个同源策略,即端口、主机名和协议完全一致得两个URL被称为同源。 不同源的网页,不能共享数据 这就造成了一个问题,前、后端的URL如果不相同,应该怎么共享数据呢? 三种方法:CORS,JSONP,反向代理。 它们都需要后端的参与

CORS(cross origin-resource share)

步骤

  • 假设 a.com:8888 想把GET /data 共享给 b.com:7777
  • /data 在响应头设置 Access-Control-Allow-Origin:b.com:7777
  • 没了

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

  1. a.com 后端需要响应OPTIONS请求
  2. a.com后端需要响应POST请求

CORS的本质

简单请求: A 通过响应头告诉浏览器,我愿意共享给 B 复杂请求:为了防止 POST/PUT/PATCH 请求对数据造成影响,浏览器会先发 OPTIONS 请求,问A接不接受 POST/PUT/PATCH。如果接受,浏览器才会发真正的请求。

JSONP

步骤

  • 假设 a.com:8888 想把 GET /data 共享给 b.com:7777
  • b.com 提前放置一个回调把回调名告诉 a.com
  • b.com 通过 <script> 标签来请求 /data
  • a.com 后端改造/data,把JSON变成JSONP

缺点

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

JSONP的本质

取巧

  • 由于 <script> 标签不受同源策略约束,可以请求任意JS,所有后端直接把数据放到了JS里。对回调的使用是JSONP的点睛之笔

反向代理

一般通过 nginx 配置实现 步骤

  • 假设 a.com:8888 想把 GET /data 共享给 b.com:7777
  • b.com 后端提供一个 /data

(nginx配置如下) image.png

  • b.com 前端通过AJAX访问b.com/data
  • b.com/data 向 a.com/data发请求,得到响应之后给 b.com 的前端