XHR对象send方法的同异步问题
2016-03-22 16:14
309 查看
XHR对象上的send方法不仅是用于发送数据部分,只有调用了send方法,整个HTTP请求头才会被发出,然后才是真正的内容部分。如此复杂的过程在规范中也没有具体的定义,所以目前各大浏览器上的实现都存在细微的差异,特别是同异步这个大坑再次中枪。
其实我以前一直以为send方法总是同步发起的(注意这里讨论的是“发起”这个行为本身的同异步,open方法的第三个参数始终为true,不讨论false的情况),还在讨论同异步的文章中使用了XHR对象的例子,现在看来确实是个不恰当的例子。在一些浏览器中XHR对象的send方法确实是同步发起的,但并不是所有浏览器都这样,可以通过下面的实验来证实(NodeJS
的部分需要 harmony 和 use_strict):
Chrome39:请求同步发出,死循环不会影响请求
Firefox33:请求被注册到下一个消息中异步发出
IE11:请求的头部分同步发出,内容部分被注册到下一个消息中异步发出
这个结果对实际运用有什么影响呢?在同步过程中多次调用open方法就能看出差异。XHR对象在调用open方法时会停止原来的工作,于是有以下几种情况:
Chrome的send是同步发出的,即使在send之后马上调用open也无法停止已经send的东西了,已经泼出去的水,根本停不下来。
Firefox就完全不同,由于是注册到下一个消息中,send后马上调用open就会取消掉原先注册但还没执行到的动作。
IE比较奇葩,在调动send时头已经发出了,这部分是收不回来的。send后马上调用open只能阻止内容部分的发出。
源引:https://www.web-tinker.com/article/20790.html
一个精密的实验
其实我以前一直以为send方法总是同步发起的(注意这里讨论的是“发起”这个行为本身的同异步,open方法的第三个参数始终为true,不讨论false的情况),还在讨论同异步的文章中使用了XHR对象的例子,现在看来确实是个不恰当的例子。在一些浏览器中XHR对象的send方法确实是同步发起的,但并不是所有浏览器都这样,可以通过下面的实验来证实(NodeJS的部分需要 harmony 和 use_strict):
//nodejsrequire('http').createServer(function(request,response){ response.setHeader('Content-Type','text/html'); if(request.url=='/test'){ console.log(request.url); let connection=request.connection; connection.write('HTTP/1.1 100 Continue\n\n'); console.log(100); request.on('data',function(e){ console.log(e+""); response.end('ok'); }); }else{ let path=process.cwd()+request.url; require('fs').readFile(path,function(error,data){ response.end(error?'error':data); }); };}).listen(1234);
<!--test.html--> <script> var xhr=new XMLHttpRequest; xhr.onreadystatechange=function(){ console.log(xhr.readyState,xhr.status); }; xhr.open("POST","test"); xhr.send("data"); var t=new Date; while(new Date-t<3000); </script>这个测试在三大主流浏览器上测试会得到三个不同的结果:
Chrome39:请求同步发出,死循环不会影响请求
Firefox33:请求被注册到下一个消息中异步发出
IE11:请求的头部分同步发出,内容部分被注册到下一个消息中异步发出
实验结果影响的现实
这个结果对实际运用有什么影响呢?在同步过程中多次调用open方法就能看出差异。XHR对象在调用open方法时会停止原来的工作,于是有以下几种情况:Chrome的send是同步发出的,即使在send之后马上调用open也无法停止已经send的东西了,已经泼出去的水,根本停不下来。
Firefox就完全不同,由于是注册到下一个消息中,send后马上调用open就会取消掉原先注册但还没执行到的动作。
IE比较奇葩,在调动send时头已经发出了,这部分是收不回来的。send后马上调用open只能阻止内容部分的发出。
源引:https://www.web-tinker.com/article/20790.html
相关文章推荐
- 在ios7及以上系统中在UINavigationBar中添加UITextField或者UISearchbar时不显示输入光杆问题及解决
- C++面试题30道
- [leetcode]Path Sum II
- SQLite性能和限制 多进程
- Android RelativeLayout 属性
- JavaSE入门学习31:Java常用类之Math类
- 【iOS开发系列】collectionView头部悬浮
- tcpdump参数应用
- HTML CSS样式
- HTML样式表,选择器
- RadioGroup调用setcheck(bool)方法时,onCheckedChanged方法被执行多次解决办法
- Anroid开发:友盟分享SDK v5使用指南(Android Studio)
- Viewpager结合RadioGroup切换的卡顿,不流畅问题
- vnc的简单配置
- JavaScript中对象的创建方法与属性的添加
- 多个模型 在 tableview
- JDBC连接数据库
- Android关于序列化
- PHP转换SQLite数据库为MySQL
- iOS 开发之照片框架详解(3)