由于同源策略的限制,xhr;不能进行不同源之间的请求,但是在实际情况中,我们经常要进行跨域请求,因此就出现跨域资源共享。
跨域请求被分为两种:简单请求和非简单请求。
一、简单请求
简单请求就是请求方式为head、post、get之三种之一,并且头部header字段为:
-
Accept
-
Accept-Language
-
Content-Language
-
Last-Event-ID
-
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text\plain。
不满足上述条件的都为非简单请求。
在发起简单请求时,浏览器会在请求头中加入Origin字段,表明来源,值为协议+域名+端口。
二、非简单请求
在发起非简单请求之前,浏览器会先发起一个预检请求,询问服务器,当前源是否在可请求的白名单中,以及浏览器可以使用的请求方式,头部字段,如果不在白名单中,返回的响应会触发xhr的onerror函数,报错。
注意,虽然跨域不成功,浏览器会报错,但是预检请求的响应状态码还是200。
遇见请求的响应头部有一个Access-Control-Allow-Origin,表明了可以进行跨域请求的源。
预检请求成功之后,就会发起真正的请求,这个请求和简单请求一样。
三、JSONP
JSON是一个数据格式,而JSONP是一种技术。因为浏览器的同源策略限制,要想实现跨域比较难,所以实现跨域的另外一种方式JSONP就诞生了。
JSONP的实现比较简单,就是用一个script标签来发起请求,url后面加一个callback函数,该函数在请求成功后执行。
原理就是,script、link、img不受同源策略的限制,但是当我们使用Content-Security-Policy限制加载源时,还是不能访问,所以使用JSONP的前提是不限制加载这个源的资源。