[TOC]

聊一聊跨域

三个标签可以避开同源策略

<script src="xxx">
<img src="xxxx"/>
<link href="xxxx">

CORS需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。

浏览器会自动进行 CORS 通信,实现CORS通信的关键是后端。只要后端实现了 CORS,就实现了跨域。

限制范围

(1) Cookie、LocalStorage 和 IndexDB 无法读取。

(2) DOM 无法获得。

(3) AJAX 请求不能发送。

浏览器要引入跨域这个机制?

浏览器的同源策略

同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

配置 Access-Control-Allow-Origin源,给一个白名单

什么可以跨域

跨域请求到底有没有正常发出去并收到响应?

跨域请求可以正常发起,但是被浏览器拦截了响应

跨域方案

CORS

同源政策规定,AJAX请求只能发给同源的网址,否则就报错。

CORS背后的基本思想就是使用自定义的HTTP头部,让 服务器能声明 哪些来源可以通过浏览器访问该服务器上的资源

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。

//服务器需要声明这么一条响应头,即可轻松跨域
//PHP中的 hander() 设置,“*”号表示允许任何域向我们的服务端提交请求:
header("Access-Control-Allow-Origin: *")
//也可以设置指定的域名,如域名 http://h5.jd.com ,那么就允许来自这个域名的请求:
header("Access-Control-Allow-Origin: http://h5.jd.com")

兼容性
cors 是 ie8 和 9

window.postMessage:

document.domain

如果两个窗口一级域名相同,只是二级域名不同,那么设置上一节介绍的document.domain属性,就可以规避同源政策,拿到DOM。

chrome浏览器不允许从HTTPS协议的域 跨域访问 HTTP协议

是否了解跨域预检?

预检请求(option):在 CORS 中,可以使用 OPTIONS 方法发起一个预检请求(一般都是浏览检测到请求跨域时,会自动发起),以检测实际请求是否可以被服务器所接受

在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

跨域请求分两种:简单请求和预检请求。一次完整的请求不需要服务端预检,直接响应的,归为简单请求;而响应前需要预检的,称为预检请求

OPTIONS /resources/post-here/ HTTP/1.1 
Host: bar.other 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Connection: keep-alive 
Origin: http://foo.example 
Access-Control-Request-Method: POST 
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

什么时候发送预检请求?

preflight

当请求满足下述任一条件时,即应首先发送预检请求:

使用了下面任一 HTTP 方法:
PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH
人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type (but note the additional requirements below)
DPR
Downlink
Save-Data
Viewport-Width
Width
 Content-Type 的值不属于下列之一:
application/x-www-form-urlencoded
multipart/form-data
text/plain

什么时候不发送预检请求?

OPTIONS请求快速返回

if (req.method == "OPTIONS") {
    res.send(200);
  }

AJAX

  • JSONP
  • WebSocket
  • CORS

JSONP

它的基本思想是,网页通过添加一个