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. Alpha冲刺第9天

    Alpha第9天 1.团队成员 郑西坤 031602542 (队长) 陈俊杰 031602504 陈顺兴 031602505 张胜男 031602540 廖钰萍 031602323 雷光游 03160 ...

  2. Linux命令(一) pwd ,cd

    1.pwd命令 以绝对路径的方式显示当前所处的工作目录,从根目录 / 开始,每一级目录用 / 分隔.第一个 / 表示根目录,最后一个目录是当前目录.当不知道当前处于哪个目录的时候,使用 pwd 命令就 ...

  3. BroadcastReceiver介绍

    参考资料 : 基础总结篇之五:BroadcastReceiver应用详解 BroadcastReceiver用于接收广播信息,可以通过sendBroadcast等方法进行发送.sendBroadcas ...

  4. 【IneliJ 】使用IneliJ IDEA 2016将Java Web项目导出为War包

    本文记录使用IDEA导出war包的过程以及碰到问题的解决办法 虽说现在改用IDEA进行开发了,但还是用eclipse打war包 ….囧 这样下去不是办法... 于是今天就试着使用IDEA进行打包. 项 ...

  5. Ubutnu linux 下升级python版本,以2.x升级到3.x为例

    Linux操作系统一般 都会自带python,但是python版本会比主流低,故升级python, 主要思路:自带的python的链接link文件是在/usr/bin 下,采用sudo apt-get ...

  6. 初征——NOIP2018游记

    前言 从最初接触oi到今年noip到来,也已经将近有一年了.从对于程序一窍不懂到现在开始学习算法,只是短短的不到一年的时间罢了.这次noip,不仅仅是我oi生涯的第一次noip,更是相当于是对我这一年 ...

  7. 【poj2187】最远点对(勉强凑数)

    题目简述 输入n个点,及其坐标,n<=50000,所有坐标都是不超过10000的整数组成,没有重点. 问最远点对间的距离的平方是多少 题解 这是一道旋转卡壳的裸题 我们要求这个多边形的直径,这可 ...

  8. 【BZOJ1201】[HNOI2005]数三角形(暴力)

    [BZOJ1201][HNOI2005]数三角形(暴力) 题面 BZOJ 洛谷 题解 预处理每个点向四个方向可以拓展的最大长度,然后钦定一个点作为三角形的某个顶点,暴力枚举三角形长度,检查这样一个三角 ...

  9. spring的controller默认是单例还是多例

    转: spring的controller默认是单例还是多例 先看看spring的bean作用域有几种,分别有啥不同. spring bean作用域有以下5个: singleton:单例模式,当spri ...

  10. java基础知识学习--------之枚举类型(1)

    枚举类型的概念: /** * 目的:枚举类型 * @author chenyanlong * 日期:2017/10/22 * 网址:http://blog.csdn.net/sup_heaven/ar ...