浅谈CORS的两种请求方式

先附上HTTP中文开发手册链接:http://www.php.cn/manual/view/35588.html

参考文章:https://blog.csdn.net/qq_34125349/article/details/79720422 

CORS官方:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

简单介绍:

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。 
定义:CORS其实出现时间不短了,它在维基百科上的定义是:跨域资源共享(CORS)是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。而W3C的官方文档目前还是工作草案,但是正在朝着W3C推荐的方向前进。

简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的。

所谓跨域是指跨域名。同一域名是指协议、域名、端口三者均相同,任一不同都不属于同一域名


整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。 因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

CORS分为两种请求:

1、简单请求(满足以下条件):

  • 请求方式为HEAD、POST 或者 GET
  • http头信息不超出一下字段:Accept、Accept-Language 、 Content-Language、 Last-Event-ID、 Content-Type(限于三个值:application/x-www-form-urlencoded、multipart/form-data、text/plain)
    为什么要分为简单请求和非简单请求,因为浏览器对这两种请求方式的处理方式是不同的。

2、非简单请求 :

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

 

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

浏览器发现,这是一个非简单请求,就自动发出一个"预检"请求,要求服务器确认可以这样请求。"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。

如果你的请求方法中出现上图中的OPTIONS,就是上面所说的“预检”请求

可以在你的过滤里面判断以下,如果请求方法为" OPTIONS " 则放行。简单实现如下:

// 判断是否是预请求 OPTIONS  是则放行
				if((boolean) ((HttpServletRequest) request).getMethod().equals("OPTIONS")){
					System.out.println(((HttpServletRequest) request).getMethod());
					((HttpServletResponse) response).setStatus(HttpStatus.OK.value());
					return;
				}

如果你项目存在跨域问题:https://blog.csdn.net/qq_40437152/article/details/88866035

头信息里面,关键字段是Origin,表示请求来自哪个源。除了Origin字段,"预检"请求的头信息包括两个特殊字段。

服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。

如果浏览器否定了"预检"请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段。这时,浏览器就会认定,服务器不同意预检请求,因此触发一个错误,被XMLHttpRequest对象的onerror回调函数捕获。

  • Access-Control-Request-Method:该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,上例是PUT。
  • Access-Control-Request-Headers:该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段,上例是X-Custom-Header
  • Access-Control-Allow-Methods:该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。
  • Access-Control-Allow-Headers:如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。
  • Access-Control-Allow-Credentials: 该字段与简单请求时的含义相同。
  • Access-Control-Max-Age: 该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。
发布了43 篇原创文章 · 获赞 57 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/qq_40437152/article/details/89000525
今日推荐