测试大姐趁我下班点又提了个bug!前端你咋多个options请求?
免责声明~
任何文章不要过度深思!
万事万物都经不起审视,因为世上没有同样的成长环境,也没有同样的认知水平,更「没有适用于所有人的解决方案」;
不要急着评判文章列出的观点,只需代入其中,适度审视一番自己即可,能「跳脱出来从外人的角度看看现在的自己处在什么样的阶段」才不为俗人。
怎么想、怎么做,全在乎自己「不断实践中寻找适合自己的大道」
1 下班前的寂静
刚准备下班呢,测试大姐又给我提个bug
,你看我这就操作了一次,network
里咋有两个请求?
我心一惊,”不可能啊!我代码明明就调用一次后端接口,咋可能两个请求!“。打开她的截图一看:多个options
请求。
我不慌不忙解释道:”这不用管,是浏览器默认发送的一个预检请求“。
可测试大姐好像依旧很执着:“那这可肯定不行啊,明明一次请求,干嘛要两次呢,这不是增大服务端压力吗?”
“md,真固执啊,那就不下班了,加个钟给你讲懂!”
HTTP请求分为两种:
- 简单请求
- 非简单请求
2 简单请求
2.1 条件
- 请求方式:
HEAD
、GET
、POST
- header中只能包含以下请求头字段:
-
text/plain
-
multipart/form-data
-
application/x-www-form-urlencoded
-
Accept
-
Accept-Language
-
Content-Language
- Content-Type所指的媒体类型值仅仅限于下列三者之一
2.2 浏览器的不同处理方式
简单请求,若请求跨域,浏览器会放行让请求发出。浏览器会发cors
请求,并携带origin
。此时不管服务端返回啥,浏览器都会把返回拦截,并检查返回的response
的header
中有无Access-Control-Allow-Origin
:
- 这头部信息的值通常为请求的
Origin
值,表示允许该来源的请求说明资源是共享的,可以拿到 - 如果
Origin
头部信息的值为"*"(表示允许来自任何来源的请求)但这种情况下需要谨慎使用,因为它存在安全隐患 - 如没有这个头信息,说明服务端没有开启资源共享,浏览器会认为这次请求失败终止这次请求,并且报错。
3 非简单请求
只要不满足简单请求的条件,都是非简单请求。
发出非简单cors
请求,浏览器会做一个http
的查询请求(预检请求)即options
。options
请求会按照简单请求来处理。
为啥要做一次options
请求?
检查服务器是否支持跨域请求,并确认实际请求的安全性。预检请求是为保护客户端的安全,防止不受信任网站利用用户浏览器向其他网站发恶意请求。 预检请求头中除了携带了origin
字段还包含两个特殊字段:
-
Access-Control-Request-Method
: 告知服务器实际请求使用的HTTP
方法 -
Access-Control-Request-Headers
:告知服务器实际请求所携带的自定义首部字段
如:
OPTIONS /resources/post-here/ HTTP/1.1
Host: bar.other
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
以上报文中就可以看到,使用OPTIONS
请求,浏览器根据上面的使用的请求参数来决定是否需要发送,这样服务器就可以回应是否可以接受用实际的请求参数来发送请求。
-Access-Control-Request-Method
告知服务器,实际请求将使用 POST
方法
Access-Control-Request-Headers
告知服务器,实际请求将携带两个自定义请求标头字段:X-PINGOTHER
与 Content-Type
。服务器据此决定,该实际请求是否被允许。
啥时触发预检请求?
- 发送跨域请求时,请求头中包含了一些非简单请求的头信息,如自定义头(custom header)
- 发送跨域请求时,使用了 PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH等请求方法
“大姐你听懂了吗?所以这不是 bug,赶紧把它关掉吧!”
大姐漏出了澄澈的目光,好吧
4 上案例
这下测试大姐终于半信半疑地关闭了Bug。
5 假如世上没有测试大姐
我说假如啊!你的测试老大姐就是说:我不懂你说的这些,我不管,反正我现在想看到的是在浏览器里面只有一次网络请求,你自己看着办吧,bug 我留在这了,你自己处理!
爱!浏览器厂商为了保证安全性,禁止了跨域,可最终还是程序员承受了所有优化的代价!
写在最后
公众号
:JavaEdge
专注分享软件开发全生态相关技术文章
、视频教程
资源、热点资讯等,如果喜欢我的分享,给 🐟🐟 点一个赞
👍 或者 ➕关注
都是对我最大的支持。
文章转载自公众号: JavaEdge