Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

CORS非主流HTTP方法的性能问题

  也许看到这个标题和多人会有这样的想法:HTTP方法不都是一个请求一样响应吗?它们能有什么性能问题?博主又开始胡说八道了!但无论如何,这个问题还真是存在的,在现代浏览器上,使用非主流的HTTP方法会带来额外的请求,这直接影响性能!有数据有真相!

HTTP方法分类

  HTTP的设计本身不是为了Web而存在,只是由于HTTP适合Web,所以它们自然就在一起了。RFC2616中虽然只说GETHEAD方法是服务器必须实现的,实际上对于Web来说POST也是一个必要方法。为什么我突然扯这么远呢?因为GETPOSTHEAD,这三个方法对于Web而言属于主流HTTP方法。与之相对的就是DELETEPUTPATCH之类的非主流方法。

为RESTful默哀

  RESTful的“增删改查”应该是POSTDELETEPUTGET呀,这些应该才是主流方法吧?这是个美好的愿望,其实我个人是挺喜欢的RESTful的,但现实总是客观地,令人无法抗拒。这里我也只能为RESTful默哀。

令人悲伤的现实

  前面啰嗦了一大堆,现在要开始进入正题了。为什么CORS时非主流HTTP方法在性能上被坑了呢?因为浏览器不知道目标服务器是否实现了请求所需的方法,会先发起一个请求检测服务器是否支持,支持后才真正发起请求。而这个检测通过OPTIONS方法发起的,我们可以直接在浏览器的控制台中观察到。下面是测试代码:
//nodejs
require("http").createServer(function(req,res){
  //加载测试页面
  if(req.url=="/test.html")
    return require("fs").readFile("test.html",function(err,dat){
      res.setHeader("Content-Type","text/html");
      res.end(dat);
    });
  //测试请求
  new Promise(function(resolve){
    console.log(req.method+" "+req.url);
    if(req.method=="OPTIONS")setTimeout(resolve,2000);
    else resolve();
  }).then(function(){
    res.setHeader("Access-Control-Allow-Origin","http://127.0.0.1:1234");
    res.setHeader("Access-Control-Allow-Methods","DELETE,PUT,PATCH");
    res.end(req.method+" "+req.url);
  }).catch(function(e){
    console.log(e);
  });
}).listen(1234);
<!--test.html-->
<script>
void function(){
  var tests=["POST","DELETE","PUT","GET","HEAD","PATCH"];
  for(var i=0;i<tests.length;i++)void function(i){
    var xhr=new XMLHttpRequest;
    xhr.open(tests[i],"//localhost:1234");
    xhr.send();
  }(i);
}();
</script>

  这个测试中我特意让OPTIONS方法延迟两秒,测试结果是只要OPTIONS没有完成,真正的请求就不会被发起。也就是说,这种情况下非主流HTTP方法需要两次HTTP请求,其开销是主流HTTP方法的两倍。

怎么办?

  目前的Web上如果没有特殊需求还是不建议使用非主流HTTP方法了。如果要开发RESTful风格的API,可以考虑使用X-HTTP-Method-Override之类的请求头来传输逻辑方法。真正发起的请求依然使用主流的GET和POST。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^