1、背景
在前后端分离的项目中经常会遇到跨域请求的问题,如果没有进行跨域配置,会浏览器请求失败。我一般采用两种解决方案:
1、采用nginx进行转发,是前后端服务处于同一个域下面,从根本上避免跨域问题。
2、后端服务做一些配置,允许请求跨域,从而解决浏览器跨域问题。但是有时候浏览器还会发送OPTIONS请求。
2、跨域请求
跨域请求的介绍,以及处理方式可以看https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS,说的非常详细
简单说就是,浏览器地址栏中的的域和即将加载的请求的域不是同一个,比如域名或端口不同,浏览器就会把这个当成跨域请求,如果服务端没有正确的返回对应的响应头,那么请求就会被拦截。导致请求失败。
3、两种跨域请求方式
浏览器将CORS请求分为两类:简单请求(simple request)和需要预检的请求(Preflighted requests),这两种方式有什么区别?
简单请求不会发送CORS preflight,也就是正式请求前不会发送OPTIONS请求,而是添加必要的请求头后直接发送请求。必须同时满足以下几个要求才能称之为简单请求:
- 请求头必须是下面三个中的一个:
- 除了浏览器自动追加的一些头 (比如,
Connection
,User-Agent
, 或者其他“Forbidden header name”), 其他能够添加的头只能是下面中的几个: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
- No event listeners are registered on any
XMLHttpRequestUpload
object used in the request; these are accessed using theXMLHttpRequest.upload
property. - No
ReadableStream
object is used in the request.
不满足上面条件的跨域请求都称为需要预检的请求,请求前都会先发送OPTIONS请求。
4、预检的请求(Preflighted requests)
不是简单请求,浏览器在跨域请求前都会发送预检,主要是把即将要进行的跨域请求的信息发送给服务端,看服务端受否支持,如果支持,则发送对应的响应头,这时才正式发送跨域请求。
例如下面的预检请求,告诉服务端,接下来的跨域请求时post,携带了简单请求外的一些头X-PINGOTHER, Content-Type。如果服务端允许此次跨域请求,那么首先需要合理的响应OPTIONS请求,如:
Access-Control-Allow-Origin: http://foo.example 允许http://foo.example的域的请求
Access-Control-Allow-Methods: POST, GET, OPTIONS 支持跨域的方法有这三个
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type 支持跨域的头有
Access-Control-Max-Age: 86400
浏览器收到响应后,如果响应满足那么则正式发送跨域请求。
OPTIONS /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
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
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
原文地址:https://www.cnblogs.com/lilinwei340/p/10177132.html