复杂请求的跨域解决方法
简单请求遇到跨域问题时,只需要在服务器端设置响应头中加入允许跨域的头部信息即可。
当遇到复杂请求时,浏览器为了防止跨域请求无端对服务器数据造成损坏会先发送一个 Options 的预检请求。服务器应该对其进行处理,决定是否允许当前客户端进一步发起跨域请求。随后浏览器会根据 Options 请求的响应信息来决定是否进行下一步真实的请求。
服务器在此次 Options 请求的返回内容中还可以指示浏览器,是否在下次请求携带相关的 Cookie 或者 Http Authentication 数据过来。
什么是简单请求
- 仅使用 Get 方法的请求。
- 仅使用 Head 方法的请求。
- 仅使用 Content-Type 为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 发起的 Post 请求。
什么是复杂请求
不满足简单请求条件的都属于复杂请求。
解决复杂请求下的跨域问题
1<?php
2
3class CORSMiddleware
4{
5 public function handle($request, Closure $next)
6 {
7 // 跨域请求时浏览器会先使用 options 方法判断是否允许当前域名发送跨域请求
8 $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
9
10 $allow_origin = array(
11 'http://localhost:8888',
12 'http://test.com',
13 'https://test.com',
14 );
15
16 // 如果请求方法为 options, 加入允许跨域响应头并直接发送响应信息
17 if ($request->isMethod('options') && in_array($origin, $allow_origin)) {
18 header("Access-Control-Allow-Methods: POST, GET, PATCH, PUT, DELETE");
19 header("Access-Control-Allow-Origin:".$origin);
20 header("Access-Control-Allow-Headers: Content-Type, X-Auth-Token, Origin");
21 header("Access-Control-Allow-Credentials: true");
22
23 return response('OK', '200');
24 }
25
26 if (in_array($origin, $allow_origin)) {
27 header("Access-Control-Allow-Methods: POST, GET, PATCH, PUT, DELETE");
28 header("Access-Control-Allow-Origin:".$origin);
29 header("Access-Control-Allow-Headers: Content-Type, X-Auth-Token, Origin");
30 header("Access-Control-Allow-Credentials: true");
31 }
32
33 return $next($request);
34 }
35}