同源策略、CORS跨域

为啥会出现跨域  

我们发送的请求通常包含这三部分:协议+域名+端口。如果浏览器发送的ajax 请求和当前界面的 url 的这三部分全部相同即为同源,反之不同源。
如果没有同源策略,假设用户登陆网站 a 后又去访问 b 网站,那么 b 网站就可以窃取用户在网站 a 的 cookie 进而冒充用户。

注意,我们常说的同源策略是针浏览器针对 ajax 的限制!!ajax 请求可以到达服务器并响应,但是浏览器会对响应进行校验,非同源则跨域。

跨域解决几种解决方案

CORS(corss origin resource sharing)

CORS(跨域资源共享),是一种基于 HTTP 头的机制,该机制需要浏览器和服务器同时支持,

对于前端而言不需要做任何操作,浏览器在发送请求时会自动带上 cors 请求头,我们只需要在服务器的响应头进行设置即可,只要 HTTP 响应头中包含相应的 CORS 响应头即可。
CORS 机制在老版本的浏览器中不支持,现代浏览器都支持 CORS。在使用 CORS 发送 AJAX 请求时浏览器端代码和过去一致,服务器端仅需要配置 CORS 的响应头。

服务器需要设置的响应头如下: 

对于复杂请求,在正式请求发送前会有一个预检请求 OPTIONS 来询问服务器,是否允许跨域请求,请求头包含这些东西:

OPTIONS /cors HTTP/1.1
    Origin: http://localhost:8888 请求来源
    Access-Control-Request-Method: GET 请求方法
    Access-Control-Request-Headers: X-Custom-Header 额外的头信息

因为我们服务器的响应头已经配置了哪些请求方法、哪些请求源可以跨域,浏览器会首先检查服务器对预检请求的响应,如果响应中包含了允许跨域的 CORS 响应头,浏览器会继续发送实际的请求。

复杂请求和简单请求

简单请求

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

复杂请求

  • 请求方法:put、delete

一般认为 axios 是复杂请求,因为 axios 默认会添加一些自定义头部,尤其是在处理 POST 请求时。以下是几个常见的例子:

  • Content-Type:默认情况下,Axios 会将  Content-Type  设置为  application/json,这是一个常见的自定义请求头。当你发送 JSON 数据时,浏览器会认为这个请求是复杂请求,需要发送预检请求。
  • Authorization:如果请求中包含了  Authorization  头,这会使请求变得复杂,浏览器会触发预检请求。
  • 跨域请求时的凭证:如果请求设置了  withCredentials: true(允许跨域请求携带 cookie 或其他凭证信息),也可能导致浏览器将请求视为复杂请求。

服务器代理

前端 Nginx 代理

JSONP

Jsonp 是最早的跨域解决方案,利用script 标签可以跨域的原理实现
缺点是只能发起 GET 请求
原理:
Jsonp 其实就是一个跨域解决方案。跨域请求数据是不可以的,但是跨域请求 js 脚本是可以的。可以把数据封装成一个 js 语句,做一个方法的调用。跨域请求 js 脚本可以得到此脚本。得到 js 脚本之后会立即执行。可以把数据做为参数传递到方法中。就可以获得数据。从而解决跨域问题。
比如

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计