浏览器在什么情况下会发起options预检请求?

在非简单请求且跨域的情况下,浏览器会发起options预检请求。
Preflighted Requests是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。
下面的情况需要进行预检
6.浏览器的跨域请求问题 - 图1

关于简单请求和复杂请求:

1 简单请求

简单请求需满足以下两个条件

  1. 请求方法是以下三种方法之一:
    • HEAD
    • GET
    • POST
  2. HTTP 的头信息不超出以下几种字段
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type: 只限于 (application/x-www-form-urlencoded、multipart/form-data、text/plain)

2 复杂请求

非简单请求即是复杂请求
常见的复杂请求有:

  1. 请求方法为 PUT 或 DELETE
  2. Content-Type 字段类型为 application/json
  3. 添加额外的http header 比如access_token

在跨域的情况下,非简单请求会先发起一次空body的OPTIONS请求,称为”预检”请求,用于向服务器请求权限信息,等预检请求被成功响应后,才发起真正的http请求。

浏览器的预检请求结果可以通过设置Access-Control-Max-Age进行缓存

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
  7. </head>
  8. <body>
  9. <button type="button" id="query">请求数据</button>
  10. <div id="content" style="background-color: aquamarine; width: 300px;height: 500px"></div>
  11. </body>
  12. <script type="text/javascript">
  13. $("#query").click(function () {
  14. $.ajax(
  15. {
  16. url:"http://127.0.0.1:8021/u/v1/user/list",
  17. dataType: "json",
  18. type: "get",
  19. beforeSend: function(request) {
  20. request.setRequestHeader("x-token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MSwiTmlja05hbWUiOiJib2JieTAiLCJBdXRob3JpdHlJZCI6MSwiZXhwIjoxNjAzMjY5NDk3LCJpc3MiOiJpbW9vYyIsIm5iZiI6MTYwMDY3NzQ5N30.7fr8FaEXP-51bxVoocyXelBmwLK3q7to39HuhrpF6eE")
  21. },
  22. success: function (result) {
  23. console.log(result.data);
  24. $("#content").text(result.data)
  25. },
  26. error: function (data) {
  27. alert("请求出错")
  28. }
  29. }
  30. );
  31. });
  32. </script>
  33. </html>