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

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);
}

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

(0)

相关推荐

  • Ajax核心XMLHttpRequest总结

    Ajax:即"Asynchronous JavaScript and XML"(异步JavaScript和XML),一门综合性的技术:运用JavaScript对象XMLHttpRequest进行异步数据交换:JavaScript操作DOM实现动态效果:运用XHTML+CSS表达信息:XML和XSLT操作数据.此篇文章重点介绍使用XMLHttpRequest对象与服务器端进行异步数据交换.     使用方法      XMLHttpRequest五步使用法: 复制代码 代码如下: 1.创

  • AJax 学习笔记一(XMLHTTPRequest对象)

    现在很多公司都在做标准的静态页面,为了增强客户的体验效果,经常会涉及到AJax效果,而设计AJax使用的一种重要技术(工具)就是XMLHttpRequest对象了.今天学习了点关于XMLHttpRequest对象的一些方法和属性,有点体会,在这里也想记录起来. 1.何为XMLHttpRequest 定义:XMLHttp是一套可以在Javascript.VbScript.Jscript等脚本语言中通过http协议传送或从接收XML及其他数据的一套API.XmlHttp最大的用处是可以更新网页的部分

  • 浅谈jQuery异步对象(XMLHttpRequest)

    我们先来看看异步对象五部曲 这是post请求的. 复制代码 代码如下: //1.00创建异步对象             var xhr = new XMLHttpRequest();             //2.0             xhr.open("post", url,params, true);             //3.0将参数使用Formdata属性传递             xhr.setRequestHeader("Content-Type

  • XMLHttpRequest对象_Ajax异步请求重点(推荐)

    一.XMLHttpRequest对象 1.Ajax能够是实现异步传输,所依赖的就是JavaScript中的XMLHttpRequest 2.XMLHttpRequest对象是XMLHttp组件的对象,它是一个抽象对象,允许脚本从服务器获取返回的eXML数据或将数据发送到服务器端 3.XMLHttpRequest可以实现客户端与服务器只进行数据层面的交互,不必每次刷新页面 4.XMLHttpRequest最早在Microsoft Internet Explorer5.0中作为一个ActiveX控件

  • 如何用ajax来创建一个XMLHttpRequest对象

    我每次创建一个对象,都要这样复杂吗?如下代码: JScript code: "testAjax.htm" 文件: 复制代码 代码如下: <html> <body> <script type="text/javascript"> function ajaxFunction() { var xmlHttp; try { // Firefox,Opera 8.0+,Safari xmlHttp=new XMLHttpRequest();

  • 详解XMLHttpRequest(一)同步请求和异步请求

    XMLHttpRequest 让发送一个HTTP请求变得非常容易.你只需要简单的创建一个请求对象实例,打开一个URL,然后发送这个请求.当传输完毕后,结果的HTTP状态以及返回的响应内容也可以从请求对象中获取. 通过XMLHttpRequest生成的请求可以有两种方式来获取数据,异步模式或同步模式.请求的类型是由这个XMLHttpRequest对象的open()方法的第三个参数async的值决定的.如果该参数的值为false,则该XMLHttpRequest请求以同步模式进行,否则该过程将以异步

  • 一文详解MySQL主从同步原理

    目录 1. MySQL主从同步实现方式 2. MySQL主从同步的作用 一主多从架构 双主多从架构 3. 主动同步的原理 4. 主从同步延迟问题 主从同步延迟的原因有哪些? 主从同步延迟的解决方案? 5. 如何提升主从同步性能 从库开启多线程复制 修改同步模式,改为异步 修改从库Bin Log配置 知识点总结 1. MySQL主从同步实现方式 MySQL主从同步是基于Bin Log实现的,而Bin Log记录的是原始SQL语句. Bin Log共有三种日志格式,可以binlog_format配置

  • 详解ES9的新特性之异步遍历Async iteration

    异步遍历 在讲解异步遍历之前,我们先回想一下ES6中的同步遍历. 根据ES6的定义,iteration主要由三部分组成: Iterable 先看下Iterable的定义: interface Iterable { [Symbol.iterator]() : Iterator; } Iterable表示这个对象里面有可遍历的数据,并且需要实现一个可以生成Iterator的工厂方法. Iterator interface Iterator { next() : IteratorResult; } 可

  • 详解MySQL实时同步到Oracle解决方案

    1 需求概述 将MySQL5.6生产库多张表的数据实时同步到Oracle11g数据仓库,MySQL历史数据700G,平均每天产生50G左右日志文件,MySQL日志空间50G,超过后滚动删除日志文件.整个同步过程不可影响MySQL业务操作. 2 技术原理 采用灵蜂数据集成软件BeeDI将MySQL数据实时同步到Oracle,通过ETL全量同步历史数据,通过日志解析方式实时同步增量数据. 受限于日志空间,如果将所有历史数据一次性同步,需要的时间会超过一天,全量同步过程产生的日志会被删除,造成实时日志

  • 详解java 中Spring jsonp 跨域请求的实例

    详解java 中Spring jsonp 跨域请求的实例 jsonp介绍 JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏览器的跨域数据访问的问题.由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外.利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSO

  • 全面解析iOS中同步请求、异步请求、GET请求、POST请求

    先给大家分别介绍下iOS中同步请求.异步请求.GET请求.POST所代表的意思,然后在逐一通过实例给大家介绍. 1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然可以对UI进行操作,程序可以继续运行 3.GET请求,将参数直接写在访问路径上.操作简单,不过容易被外界看到,安全性不高,地址最多255字节: 4.POST请求,将参数放到body里面.P

  • java并发编程专题(三)----详解线程的同步

    有兴趣的朋友可以回顾一下前两篇 java并发编程专题(一)----线程基础知识 java并发编程专题(二)----如何创建并运行java线程 在现实开发中,我们或多或少的都经历过这样的情景:某一个变量被多个用户并发式的访问并修改,如何保证该变量在并发过程中对每一个用户的正确性呢?今天我们来聊聊线程同步的概念. 一般来说,程序并行化是为了获得更高的执行效率,但前提是,高效率不能以牺牲正确性为代价.如果程序并行化后, 连基本的执行结果的正确性都无法保证, 那么并行程序本身也就没有任何意义了.因此,

  • 详解c# 线程同步

    一.线程同步概述 前面的文章都是讲创建多线程来实现让我们能够更好的响应应用程序,然而当我们创建了多个线程时,就存在多个线程同时访问一个共享的资源的情况,在这种情况下,就需要我们用到线程同步,线程同步可以防止数据(共享资源)的损坏. 然而我们在设计应用程序还是要尽量避免使用线程同步, 因为线程同步会产生一些问题: 1. 它的使用比较繁琐.因为我们要用额外的代码把多个线程同时访问的数据包围起来,并获取和释放一个线程同步锁,如果我们在一个代码块忘记获取锁,就有可能造成数据损坏. 2. 使用线程同步会影

  • Java并发编程之详解CyclicBarrier线程同步

    CyclicBarrier线程同步 java.util.concurrent.CyclicBarrier提供了一种多线程彼此等待的同步机制,可以把它理解成一个障碍,所有先到达这个障碍的线程都将将处于等待状态,直到所有线程都到达这个障碍处,所有线程才能继续执行. 举个例子:CyclicBarrier的同步方式有点像朋友们约好了去旅游,在景点入口处集合,这个景点入口就是一个Barrier障碍,等待大家都到了才一起进入景点游览参观. 进入景点后大家去爬山,有的人爬得快,有的人爬的慢,大家约好了山顶集合

  • 详解JavaScript for循环中发送AJAX请求问题

    首先说,出现这个问题的场景是很少见的,因为有太多更好解决方法.今天搞ajax的时候,一个有趣的地方,,每个迭代中都要发送一个get请求,因为迭代的速度太快,一个请求还没有完成就进行下一个迭代,在chrome和ff上,除最后一个请求外,其它请求都被取消了.所以该怎么办呢?设置延时(不太好)还是其他办法?  办法有很多,比如设置休眠,迭代等等, 我采用的是另外两种解决办法.  一.同步的ajax请求,而ajax请求默认是异步的,所以要设置为false. function creatXMLHttpRe

随机推荐