浏览器在什么情况下会发起options预检请求?
在非简单请求且跨域的情况下,浏览器会发起options预检请求。
Preflighted Requests是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。
下面的情况需要进行预检
关于简单请求和复杂请求:
1 简单请求
简单请求需满足以下两个条件
- 请求方法是以下三种方法之一:
- HEAD
- GET
- POST
- 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
- 添加额外的http header 比如access_token
在跨域的情况下,非简单请求会先发起一次空body的OPTIONS请求,称为”预检”请求,用于向服务器请求权限信息,等预检请求被成功响应后,才发起真正的http请求。
浏览器的预检请求结果可以通过设置Access-Control-Max-Age进行缓存
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<button type="button" id="query">请求数据</button>
<div id="content" style="background-color: aquamarine; width: 300px;height: 500px"></div>
</body>
<script type="text/javascript">
$("#query").click(function () {
$.ajax(
{
url:"http://127.0.0.1:8021/u/v1/user/list",
dataType: "json",
type: "get",
beforeSend: function(request) {
request.setRequestHeader("x-token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MSwiTmlja05hbWUiOiJib2JieTAiLCJBdXRob3JpdHlJZCI6MSwiZXhwIjoxNjAzMjY5NDk3LCJpc3MiOiJpbW9vYyIsIm5iZiI6MTYwMDY3NzQ5N30.7fr8FaEXP-51bxVoocyXelBmwLK3q7to39HuhrpF6eE")
},
success: function (result) {
console.log(result.data);
$("#content").text(result.data)
},
error: function (data) {
alert("请求出错")
}
}
);
});
</script>
</html>