0%

非简单请求

和简单请求相比,非简单请求是那种对服务器有特殊要求的请求,比如请求方式是put、delete或者Content-Type字段类型是application/json
非简单的CORS请求会在正式通信之前,增加一次HTTP查询请求,称为‘预检请求’。

预检请求

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

预检请求的询问

1
2
3
4
5
6
7
8
9
10
11
12
$http({
method: 'PUT',
url: apiUrl + '/account.php/login/login',
params: params,
withCredentials: true,
data: params,
headers: { 'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function(result){
console.log('success');
}).catch(function(data){
console.log('error');
});

这里用$http服务发起了一个PUT类型的请求,可以看到浏览器发出了个预检请求:

1
2
3
4
5
Request URL:http://localhost:8080/tp-api/account.php/login/login?name=tony
Request Method:OPTIONS
Status Code:200 OK
Remote Address:127.0.0.1:8080
Referrer Policy:no-referrer-when-downgrade

可以看到预检请求的请求方法是OPTIONS类型的,表示这个请求是用来询问的。

服务器对预检请求的回应

我们的服务器设置是:

1
2
header("Access-Control-Allow-Origin: http://localhost:3000");
header("Access-Control-Allow-Method:POST,GET");

表示允许接收来自http://localhost:3000这个域的访问请求,并且访问方法是只允许POSTGET

所以我们在发送PUT请求的预检请求的时候服务器返回了响应:

1
2
3
4
5
6
7
8
9
Access-Control-Allow-Credentials:true
Access-Control-Allow-Method:POST,GET
Access-Control-Allow-Origin:http://localhost:3000
Connection:keep-alive
Content-Type:application/json; charset=utf-8
Date:Tue, 22 Aug 2017 08:29:34 GMT
Server:nginx/1.12.1
Transfer-Encoding:chunked
X-Powered-By:PHP/5.6.30

同时浏览器抛出错误:

1
XMLHttpRequest cannot load http://localhost:8080/tp-api/account.php/login/login?name=tony. Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.

我们给服务器配置上允许接收PUT请求就ok了。

正常请求

一旦服务器通过了预检请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个origin头信息字段。

码字辛苦,打赏个咖啡☕️可好?💘