详解XMLHttpRequest(一)同步请求和异步请求_javascript技巧

XMLHttpRequest 让发送一个HTTP请求变得非常容易。你只需要简单的创建一个请求对象实例,打开一个URL,然后发送这个请求。当传输完毕后,结果的HTTP状态以及返回的响应内容也可以从请求对象中获取。 

通过XMLHttpRequest生成的请求可以有两种方式来获取数据,异步模式或同步模式。请求的类型是由这个XMLHttpRequest对象的open()方法的第三个参数async的值决定的。如果该参数的值为false,则该XMLHttpRequest请求以同步模式进行,否则该过程将以异步模式完成。

两种通信模式:同步和异步请求: 

同步请求
 主线程中的同步请求会阻塞页面,由于对用户体验的糟糕效果,部分最新浏览器在主线程上的同步请求已经被弃用。在极少数情况下,使用同步模式的XMLHttpRequests会比使用异步模式更适合。

 1.在Worker中使用XMLHttpRequest时,同步请求比异步请求更适合。
 主页中代码:

 <script type="text/javascript">
 var oMyWorker = new Worker("myTask.js");
 oMyWorker.onmessage = function(oEvent) {
  alert("Worker said: " + oEvent.data);
 };
 oMyWorker.postMessage("Hello");
</script>
myFile.txt ( XMLHttpRequest对象同步请求的文件):
Hello World!!

包含了Worker代码:myTask.js

 self.onmessage = function (oEvent) {
 if (oEvent.data === "Hello") {
var oReq = new XMLHttpRequest();
oReq.open("GET", "myFile.txt", false); // 同步请求
oReq.send(null);
self.postMessage(oReq.responseText);
 }
}; 

注意: 由于使用了Worker,所以该请求实际上也是异步的.
 可以使用类似的方法,让脚本在后台与服务器交互,预加载某些内容.查看使用web workers了解更多详情

 2.不得不使用同步请求的情况
 在少数情况下,只能使用同步模式的XMLHttpRequest请求.比如在 window.onunload和window.onbeforeunload 事件处理函数中。在页面unload事件处理函数中使用异步的XMLHttpRequest会引发这样的问题:当响应返回之后,页面已经不复存在,所有变量和回调函数也已经销毁.结果只能引起一个错误 ,“函数未定义”。解决办法是在这里使用同步模式的请求,这样的话,当请求完成之前,页面不会被关闭.

 window.onbeforeunload = function () {
 var oReq = new XMLHttpRequest();
 oReq.open("GET", "logout.php?nick=" + escape(myName), false); // 同步请求
 oReq.send(null);
 if (oReq.responseText.trim() !== "已退出"); { // "已退出"是返回的数据
return "退出失败,您想手动执行退出吗?";
 }
}; 

异步请求
 使用异步模式的话,当数据完全请求回来以后,会执行一个指定的回调函数, 在执行请求的同时,浏览器可以正常的执行其他事务的处理。 

3.例子: 创建一个标准的方法来读取外部文件
 在一些需求情况下,必须读取多个外部文件. 这是一个标准的函数. 该函数使用XMLHttpRequest对象进行异步请求.而且可以为每个文件读取完成后指定不同的回调函数.

 function loadFile (sURL, timeout, fCallback /*, 传入参数1, 传入参数2, 等 */) {
 var aPassArgs = Array.prototype.slice.call(arguments, 3), oReq = new XMLHttpRequest();
 oReq.ontimeout = function() {
console.log("请求超时.");
 }
 oReq.onreadystatechange = function() {
if (oReq.readyState === 4) {
 if (oReq.status === 200) {
  fCallback.apply(oReq, aPassArgs);
 } else {
  console.log("Error", oReq.statusText);
 }
}
 };
 oReq.open("GET", sURL, true);
 oReq.timeout = timeout;
 oReq.send(null);
} 

loadFile函数的用法:

 function showMessage (sMsg) {
 alert(sMsg + this.responseText);
}
loadFile("message.txt", 200, showMessage, "New message!\\n");

第1行定义一个函数,当文件读取完毕后,fCallback函数会以第3个参数以后的所有参数为自己的参数来被调用.
第3行使用一个超时设置,来避免你的代码为了等候读取请求的返回数据长时间执行,通过为XMLHttpRequest对象的timeout 属性赋值来指定
 第6行为onreadystatechange事件句柄指定了回调函数,函数在每次执行时,检查请求是否结束(请求状态为4),如果是的话,判断请求是否成功(HTTP状态吗是否为200),如果是的话,输出页面源码,如果请求出现了错误,输出错误信息.
 第15行指定第三个参数为true,表示该请求应该以异步模式执行.

 4.例子: 使用异步请求,不使用闭包.

 function switchXHRState() {
 switch (this.readyState) {
case 0: console.log("还没调用open()方法."); break;
case 1: console.log("还没调用send()方法."); break;
case 2: console.log("已经调用send()方法,响应头和响应状态已经返回."); break;
case 3: console.log("下载中,已经得到部分响应实体."); break;
case 4: console.log("请求完成!"); this.callback.apply(this, this.arguments);
 }
};
function loadFile (sURL, fCallback /*, 传入参数1, 传入参数2, 等 */) {
 var oReq = new XMLHttpRequest();
 oReq.callback = fCallback;
 oReq.arguments = Array.prototype.slice.call(arguments, 2);
 oReq.onreadystatechange = switchXHRState;
 oReq.open("GET", sURL, true);
 oReq.send(null);
}

使用 bind: 

function switchXHRState(fCallback, aArguments) {
 switch (this.readyState) {
case 0: console.log("还没调用open()方法."); break;
case 1: console.log("还没调用send()方法."); break;
case 2: console.log("已经调用send()方法,响应头和响应状态已经返回."); break;
case 3: console.log("下载中,已经得到部分响应实体."); break;
case 4: console.log("请求完成!"); fCallback.apply(this, aArguments);
 }
};
function loadFile (sURL, fCallback /*, 传入参数1, 传入参数2, 等 */) {
 var oReq = new XMLHttpRequest();
 oReq.onreadystatechange = switchXHRState.bind(oReq, fCallback, Array.prototype.slice.call(arguments, 2));
 oReq.open("GET", sURL, true);
 oReq.send(null);
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索xmlhttprequest
, 异步请求
同步请求
javascript 异步请求、webrequest 异步请求、request请求转发详解、javascript 异步、javascript 异步编程,以便于您获取更多的相关知识。

时间: 2024-08-30 04:54:22

详解XMLHttpRequest(一)同步请求和异步请求_javascript技巧的相关文章

详解javascript实现瀑布流绝对式布局_javascript技巧

瀑布流也应该算是流行几年了吧.首先是由Pinterest掀起的浪潮,然后国内设计如雨后春笋般,冒出很多瀑布流的例子,比如,蘑菇街,Mark之(不过最近涉黄,好像被喝茶了),还有淘宝的 "哇哦". 这些都是很棒的例子, 今天我们就聊一聊瀑布流.一.绝对式布局: JS实现原理 其实瀑布式主要的难点就在于,如果将图片整齐的排列在对应的列下,以及什么时候开始刷新加载图片. 而图片整齐的排列的主要逻辑和算法即,先获取容器内可以放多少列,然后,通过计算,存放第一列的高度,再遍历剩下(除第一列的元素

图文详解JavaScript的原型对象及原型链_javascript技巧

对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__proto__混淆,二来它们之间的各种指向实在有些复杂,其实市面上已经有非常多的文章在尝试说清楚,有一张所谓很经典的图,上面画了各种线条,一会连接这个一会连接那个,说实话我自己看得就非常头晕,更谈不上完全理解了.所以我自己也想尝试一下,看看能不能把原型中的重要知识点拆分出来,用最简单的图表形式说清楚. 我们知道原型是一个对象,其他对象可以通过它实现属性继承.但是尼玛除了prototype,又有一个__

详解js界面跳转与值传递_javascript技巧

本文实例实现的功能如下:注册页(Register.js),点击注册,跳到注册结果页(RegisterResult.js),并将注册的手机号传递过去,显示xx注册成功. index.Android.js 'use strict' import React, { Component } from 'react'; import { AppRegistry,Navigator,BackAndroid} from 'react-native'; var Register = require('./stu

详解nodejs与javascript中的aes加密_javascript技巧

一.简介 1.aes加密简单来说,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用.高级加密标准已然成为对称密钥加密中最流行的算法之一. 2.AES的区块长度固定为128 比特,密钥长度则可以是128,192或256比特:而Rijndael使用的密钥和区块长度可以是32位的整数倍,以128位为下限,256比特为上限.包括AES-ECB,AES-CBC,AES-CTR,AES-OFB,AES-CFB. 3.在

详解js中Json的语法与格式_javascript技巧

JSON 文本格式在语法上与创建 JavaScript 对象的代码相同. 由于这种相似性,无需解析器,JavaScript 程序能够使用内建的 eval() 函数,用 JSON 数据来生成原生的 JavaScript 对象. JSON语法规则: 数据在 名称/值 对仲 数据由逗号分隔 花括号保存对象 方括号保存数组 JSON 名称/值 对介绍 "name":"张飞", "age":23 Json的值可以是: 数字(整数或浮点数) 字符串(要包括在

详解WordPress开发中get_current_screen()函数的使用_javascript技巧

get_current_screen() 函数是一个我们很少用到,但却超级实用的一个函数,如果你正着手于制作一个主题,却不知道文档应该放在哪里的话,那你应该看一下这个从 WordPress 3.0 才开始有的函数,该函数允许我们获得一个 WP_Screen 对象,并使用该对象的成员方法在后台里面加挂我们自定义的一个帮助菜单(该功能在,3.3版后得到完善). 如果你不喜欢将 WordPress 研究的太透彻的话,那你现在就可以拿着酱油瓶,向前打酱油去了. 引言首先,get_current_scre

详解javascript获取url信息的常见方法_javascript技巧

先以"http://www.cnblogs.com/wuxibolgs329/p/6188619.html#flag?test=12345"为例,然后获得它的各个组成部分. 1.获取页面完整的url var a=location.href; console.log(a); // "http://www.cnblogs.com/wuxibolgs329/p/5261577.html#flag?test=12345" 2.获取页面的域名 var host = windo

详解JavaScript中的Unescape()和String() 函数_javascript技巧

JavaScript中的Unescape()和String() 函数详解,具体内容如下所示: 定义和用法 JavaScript unescape() 函数可对通过 escape() 编码的字符串进行解码. 语法 unescape(string) 参数 描述 string 必需.要解码或反转义的字符串. 返回值 string 被解码后的一个副本. 说明 该函数的工作原理是这样的:通过找到形式为 %xx 和 %uxxxx 的字符序列(x 表示十六进制的数字),用 Unicode 字符 \u00xx

Javascript 异步加载详解(浏览器在javascript的加载方式)_javascript技巧

一.同步加载与异步加载的形式 1. 同步加载 我们平时最常使用的就是这种同步加载形式: <script src="http://yourdomain.com/script.js"></script> 同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止了后续的解析,因此停止了后续的文件加载(如图像).渲染.代码执行. js 之所以要同步执行,是因为 js 中可能有输出 document 内容.修改dom.重定向等行为,所以默认同步执行才是安全的. 以前的一般建议

详解前端自动化工具gulp自动添加版本号_javascript技巧

之前,我介绍了学习安装并配置前端自动化工具Gulp,觉得gulp确实比grunt的配置简单很多,于是我决定再深入学习一下gulp,就去网上查了资料,发现gulp还可以自动添加版本号,这个功能就为我平时在更新css或js时老是在客户端存在缓存导致更新后的效果无法实时展现的苦恼.所以就赶紧去试了一下,果真可以,很高兴啊,真是为项目开发,为效果的快速展现提供了很多的便利. 实现原理: 1.修改js和css文件: 2.通过对js,css文件内容进行hash运算,生成一个文件的唯一hash字符串(如果文件