和简单请求相比,非简单请求是那种对服务器有特殊要求的请求,比如请求方式是put、delete
或者Content-Type
字段类型是application/json
。
非简单的CORS请求会在正式通信之前,增加一次HTTP查询请求,称为‘预检请求’。
预检请求
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定的答复,浏览器才会发出正式的XMLHttpRequest
请求,否则就报错。
预检请求的询问
1 | $http({ |
这里用$http
服务发起了一个PUT类型的请求,可以看到浏览器发出了个预检请求:
1 | Request URL:http://localhost:8080/tp-api/account.php/login/login?name=tony |
可以看到预检请求的请求方法是OPTIONS类型的,表示这个请求是用来询问的。
服务器对预检请求的回应
我们的服务器设置是:
1 | header("Access-Control-Allow-Origin: http://localhost:3000"); |
表示允许接收来自http://localhost:3000
这个域的访问请求,并且访问方法是只允许POST
和GET
。
所以我们在发送PUT请求的预检请求的时候服务器返回了响应:
1 | Access-Control-Allow-Credentials:true |
同时浏览器抛出错误:
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头信息字段。