盒子
文章目录
  1. 一 同源策略
  2. 二 CORS:
    1. 简单请求(simple request)
      1. 2.1 基本流程
      2. 2.2 withCredentials 属性
    2. 非简单请求(not-so-simple request)
      1. 预检请求
    3. 预检响应
  3. 三 JSONP(Json with padding)

跨域

一 同源策略

浏览器处于对安全方面的考虑,不允许跨域调用其他域下的资源。当 协议,域名,端口相同的时候才算是同一个域名,否则均认为需要做跨域的处理。
可以通过以下脚本开启一个运行跨域的浏览器:

open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security

二 CORS:

简单请求(simple request)

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

2.1 基本流程

  1. 浏览器发现是跨域的话,会自动加上Origin 字段;
  2. 如果 Origin 指定的源,不在许可范围内,服务器会返回一个正常的 HTTP 回应。浏览器发现,这个回应的头信息没有包含 Access-Control-Allow-Origin字段,会抛出一个错误,可以被 XMLHttpRequest 的 onerror 回调函数捕获。但这种错误无法通过状态码识别,因为 HTTP 回应的状态码有可能是 200;
  3. 如果 Origin 指定的域名在许可范围内,服务器返回的响应会多出几个头信息字段。
Access-Control-Allow-Origin: http://api.bob.com  //该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个 *,表示接受任意域名的请求。
Access-Control-Allow-Credentials: true // 该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。服务器明确许可,可以发送 cookie
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

2.2 withCredentials 属性

CORS 请求默认不发送 cookie 和 HTTP 认证信息。如果要把 cookie 发到服务器,一方面要服务器同意,指定 Access-Control-Allow-Credentials字段:

Access-Control-Allow-Credentials: true

另一方面,开发者必须在 Ajax 请求中打开 withCredentials 属性:

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

Attention: 如果要发送 cookie,Access-Control-Allow-Origin 就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,cookie 依然遵循同源政策,只有用服务器域名设置的 cookie 才会上传,其他域名的 cookie 并不会上传,且(跨源)原网页代码中的 document.cookie 也无法读取服务器域名下的 cookie。

非简单请求(not-so-simple request)

  1. 方法:PUT 或 DELETE
  2. Content-Type:application/json

预检请求

如果浏览器发现这是一个非简单请求,就自动发出一个「预检请求(preflight)」。浏览器先询问服务器:当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 方法和头信息字段。只有得到肯定答复,浏览器才会发出正式的 XMLHttpRequest 请求否则就报错。「预检」请求用的请求方法是 OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是 Origin,表示请求来自哪个源。

除了Origin字段,预检请求的头信息包括两个特殊字段:Access-Control-Request-MethodAccess-Control-Request-Headers

预检响应

  1. AAccess-Control-Allow-Methods
  2. Access-Control-Allow-Headers
  3. Access-Control-Allow-Credentials
  4. Access-Control-Max-Age

三 JSONP(Json with padding)

w3schools: https://www.w3schools.com/js/js_json_jsonp.asp

在进行 Ajax 请求时,由于同源策略不能进行跨域请求,而<script>标签的 src 属性却可以加载跨域的 JavaScript 脚本,JSONP 就是利用这一特性实现的。与普通的 Ajax 请求不同,在使用 JSONP 进行跨域请求时,服务器不再返回 JSON 格式的数据,而是返回一段调用某个函数的 JavaScript 代码,在 src 属性中调用来实现跨域。

JSONP 的优点是兼容性好,在一些老旧的浏览器种也可以运行,但它的缺点也非常明显:

  • 只能进行 GET 请求;
  • XSS 攻击