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请求,而是添加必要的请求头后直接发送请求。必须同时满足以下几个要求才能称之为简单请求:

  不满足上面条件的跨域请求都称为需要预检的请求,请求前都会先发送OPTIONS请求。

  如下面得列子,这个跨域请求就是简单请求,满足上面提到得几个条件。

  由于是跨域请求,浏览器追加了Origin头,表示当前浏览器地址上面的域是http://foo.example。响应中多了Access-Control-Allow-Origin头,表示允许访问的域,*表示允许所有的域访问。如果服务端没有这个返回这个响应头,或者响应头中值不包含Origin中的域,浏览器就放弃这个响应。

GET /resources/public-data/ 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
Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
Origin: http://foo.example HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

4、预检的请求(Preflighted requests)

  不是简单请求,浏览器在跨域请求前都会发送预检,主要是把即将要进行的跨域请求的信息发送给服务端,看服务端受否支持,如果支持,则发送对应的响应头,这时才正式发送跨域请求。

  例如下面的预检请求,除了发送Origin头外,还发送了Access-Control-Request-Method和Access-Control-Request-Headers,用来告诉服务端,接下来的跨域请求是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

  接着看预检请求之后的请求,和简单请求一致,请求头多了Origin,响应头多了Access-Control-Allow-Origin。从这可以看出,非简单请求会发送预检请求,之后再发送正式请求,正式请求和简单请求的跨域头一致。


POST /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
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: http://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: http://foo.example
Pragma: no-cache
Cache-Control: no-cache <?xml version="1.0"?><person><name>Arun</name></person> HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain
 

http跨域时的options请求的更多相关文章

  1. 前后端分离开发,跨域时jsessionid每次请求都变化的问题解决方法

    本解决方法的使用前提是,前端开发使用的是vue,后端使用java(SpringMVC) 在前后端分离开发过程中,可能会出现因跨域而导致每次请求的jsessionid不一致的情况 解决方法: 前端:要在 ...

  2. 当跨域时,js ajax 请求出现options请求

    上面有文章说过http的options. 查了很久.试了很多版本的jQuery,下面这段代码在同事的机子上测试是没有问题的.正常 的请求, 一在我机子上面就会出现option,网上说先向服务器预检等. ...

  3. Http跨域时的Option请求

    写这篇文章时,我们碰到的一个场景是:要给R系统做一个扩展小应用,前端的html.js放在R系统里,后端需要做一个单独的站点N.B.com.这就导致了跨域问题,而且要命的是,后端同学没有权限向招聘的系统 ...

  4. JSONP跨域的script标签请求为什么不受同源策略的限制?

    在复习跨域的时候,复习到了JSONP跨域,大家都知道JSONP跨域是通过动态创建script标签,然后通过其src属性进行跨域请求的,前端需要一个数据处理的回调函数,而服务端需要配合执行回调函数,放入 ...

  5. 跨域GET、POST请求

    跨域GET.POST请求的小结 重点:跨域POST大量数据: JQuery:$.ajax/$.getJSON支持jsonp格式的跨域,但是只支持GET方式,暂不支持POST: CORS:w3c关于跨域 ...

  6. Ajax跨域(CROS)请求中的Preflighted requests

    Ajax跨域(CROS)请求中的Preflighted requests:https://www.aliyun.com/jiaocheng/862989.html 10 分钟理解跨域请求:https: ...

  7. 跨域时发送预检请求,tp5的restful无options方法的解决方案

    解决 跨域问题解决 问题:使用vue-resource发送delete请求时报options请求404 思考:明明发送的是delete请求,为何变成了options请求? 答:跨域情况下,PUT,DE ...

  8. 彻底解决Asp.netCore WebApi 3.1 跨域时的预检查204 options重复请求的问题

    Asp.netCore WebApi 3.1 跨域的预检查options问题 1:我们直接使用core跨域的中间件 ,注入跨域服务, services.AddCors(options => { ...

  9. ajax跨域POST时执行OPTIONS请求服务端返回403forbidden的解决方法

    ajax访问服务端restful api时,由于contentType类型的原因,浏览器会先发送OPTIONS请求. 本人服务端用的是spring mvc框架,web服务器用的是tomcat的,以下给 ...

随机推荐

  1. WBS功能分解及甘特图

    产品 一级子功能 二级子功能 三级子功能 时间(小时)  食物链教学工具 属性面板 功能按键 选择环境 1       自定义生物 2       生物连线与删除 5       显示食物链 1   ...

  2. mysql & java & spring transaction isolation level

    mysql /*SESSION LEVEL*/ select @@tx_isolation; /*GLOBAL LEVEL*/ select @@global.tx_isolation; select ...

  3. 用好SVN与Git,版本管理都不是问题

    介绍一下SVN SVN:代码控制器(版本控制器),主要是为了多人协同开发项目,管理代码.也可以管理个人代码.也叫程序界的”后悔药“. SVN(是subversion的简称)是近年来一款基于C/S架构的 ...

  4. JS animate动画

    <!DOCTYPE html><html lang="zh-cn"><head> <meta charset="utf-8&qu ...

  5. SpringBoot设置事务隔离等级

    "If you're gonna play the game, boy, ya gotta learn to play it right" Spring Boot 使用事务非常简单 ...

  6. Cuba项目从远程Git仓库下载步骤

    Cuba Studio 从Git远程仓库里下载代码,并且可以使用IDEA打开,需要注意的地方: 1.使用Git Gui克隆代码 也可以使用IDEA本身集成的Git下载,但是要保证:下载了项目以后,不能 ...

  7. Kakfa的设计思想

    Kafka Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实 ...

  8. 洛谷 P4568 [JLOI2011]飞行路线 解题报告

    P4568 [JLOI2011]飞行路线 题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在\(n\)个城市设有业务,设这些城市分别标记为0到\(n−1\ ...

  9. luogu1084 [NOIp2012]疫情控制 (二分答案+倍增+dfs序)

    先二分出一个时间,把每个军队倍增往上跳到不能再跳 然后如果它能到1号点,就记下来它跳到1号点后剩余的时间:如果不能,就让它就地扎根,记一记它覆盖了哪些叶节点(我在这里用了dfs序+差分,其实直接dfs ...

  10. POJ 3268 Silver Cow Party (最短路径)

    POJ 3268 Silver Cow Party (最短路径) Description One cow from each of N farms (1 ≤ N ≤ 1000) convenientl ...