笔记 - 跨域

270 阅读2分钟

同源

orgin = protocol + host + port
同源即两个 url 的协议,域名,端口完全一致。
浏览器仅允许同源的文档和脚本进行交互,如果两个 url 不同源,他们都不能获得对方的数据。

跨域

同源策略对 origin 的限制非常严格,例如 a.test.com 和 b.test.com 并不同源,但现实中这两个三级域名往往属于同一个二级域名的拥有者。 常用的跨域方法有 JSONP 和 CORS, postMessage 也可以用于跨域,但更多用于不同窗口不同页面的跨域通讯。

JSONP

Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有src这个属性的标签都拥有跨域的能力,比如<script><img><iframe>);
JSON纯字符数据格式可以简洁的描述复杂数据,JS原生支持JSON,因此我们可以轻松使用JS处理和转化JSON。

JSONP的本质是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

CORS

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

简单请求要求请求符合以下几个条件:

  1. 请求方法是以下三种方法之一:
  • HEAD
  • GET
  • POST
  1. HTTP的头信息不超出以下几种字段:
  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

如果请求符合以上要求,浏览器在请求中自动添加 Origin
如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequestonerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Credentials
  • Access-Control-Expose-Headers

Access-Control-Allow-Origin 写明了服务器所允许的 Origin,凡包含在内的源都可以进行跨域。

几乎所有浏览器都支持CORS,但 IE 版本不得低于10

参考文章:
www.jianshu.com/p/e1e2920da…
segmentfault.com/a/119000001…
www.ruanyifeng.com/blog/2016/0…
www.ruanyifeng.com/blog/2016/0…