跨域问题

CORS跨域问题

CORS跨域资源共享:跨域资源共享(CORS)是一种机制,它使用额外的HTTP头来告诉浏览器,让运行在一个与origin上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域或端口请求资源时,资源会发起一个跨域的HTTP的请求。应该算是现在比较推荐的跨域解决方案。

  • 现在浏览器将CORS的请求分成两类:简单请求非简单请求

1、简单请求

请求方式 HTTP的头信息不超过字段
HEAD Accept(客户端希望接受的类型,text/xml就是xml的类型)
GET Accept-Language(浏览器支持的语言)
POST Content-Language(精确你的语言类型,Content-Type能知道是中文还是英文,但是不知道是繁体中文还是简体中文,英语不知道是英式还是美式,而且不写默认是按文件的语言传的,同理写给用德语的人,不代表写文件的人是使用德语的,可设置语言,权重)
Content-Type(application/x-www-form-urlencoded(表单默认提交的数据)、mulitipart/form-data(需要在表单中进行上传文件提交的格式)、text/plain(纯文本))

非简单请求会发出一次预检测请求,返回码是204,预检测通过才会真正发出请求,这才返回200。这里通过前端发请求的时候增加一个额外的headers来触发非简单请求。

  • 进行带有身份凭证的CORS请求

    • 默认情况下的跨域请求都是不会把cookie发送给服务器的,在需要发送的情况下,如果是xhr,那么需要设置xhr.withCredentials=true
    • 如果是采用fetch获取的话,那么需要在request里面设置credential:’include’,
    • 但是如果服务器在预请求的时候没返回Access-Control-Allow-Crenditials:ture的话,那么在实际请求的时候,cookie是不会被发送给服务器端的,要特别注意对于简单的get请求,不会有预请求的过程
    • 那么在实际请求的时候,如果服务器没有返回Access-Control-Allow-Crenditial:true的话那么相应结果浏览器也不会交给请求者。
  • 对于附带身份凭证的请求,服务器不得设置Access-Control-Allow-Origin的值为“*”。这是因为请求的首部中携带了Cookie信息,如果Access-Control-Allow-Origin的值为“*”,请求将会失败。而将Access-Cotrol-Allow-Origin的值设置为http://www.a.com,则请求将成功执行。

  • HTTP响应首部字段

    字段 意义
    Access-Control-Allow-Origin <origin>|*,如果要发送cookies就不能将这个设置成*,必须明确设置与请求网页一致的域名。
    Access-Control-Expose-Headers XMLhttpRequest对象的getResponseHeader()方法只能获取到6个基本字段(Cache-control、Content-Language、Content-Type、Expires、Last-Modfied、Pragma)如果想要拿到其他字段,就需要在这里指定,然后getResponseHeader(“字段名”)。
    Access-Control-Max-Age 头指定了(预检)preflight请求的结果能够被缓存多久
    Access-Control-Allow-Credentials 头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容
    Access-Control-Allow-Methods 首部字段用于预检请求的响应。其指明了实际请求所允许使用的HTTP方法。(GET/PUT/POST/DELETE)
    Access-Control-Allow-Headers 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段(Content-Type),如果浏览器的请求包含Access-Control-Request-Header,那么该字段则必须,表示服务器所支持的所有头信息字段。

2、非简单请求

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUTDELETE,或者Content-Type字段类型为application/json,非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为预检请求。

预检请求包含的字段
字段 意义
Orign 表示请求来自哪个源
Access-Control-Request-Method 该字段必须,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT.
Access-Control-Request-Header 该字段是一个逗号分割的字符串,指定浏览器CORS请求会额外的发送的头信息的字段

如果返还一个没有任何CORS相关的头信息字段,这时,浏览器就会认为,服务器不同意预检请求,然后发送一个错误,被XMLhttpRqueset对象的onerror捕获。

3、如何取消ajax请求

  • 对于原生XHR对象来说,取消ajax的关键是调用XHR对象的.abort()方法
  • axios去发送请求的话,
1
2
3
4
5
6
7
8
9
10
11
var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios({
method:"GET",
url:"https:api.github.com",
cancelToken:source.token
//cancelToken的值起表示作用,标识由source控制的,将要被取消的ajax操作
})

source.cancel('message')
  • 用fetch,有var controller = new AbortControll(),可以controller.abort()

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!