HTTP请求设置时间限制
为HTTP请求设置时间限制
当XMLHttpRequest请求没有成功时,在指定的时间段后显示有帮助的信息。
XMLHttpRequest对象会打开一组异常,这些异常是连接服务器失败时由JavaScript程序产生的。为什么会发生?网络延迟可能是问题所在,或者服务器出现了错误。你并不知道你的用户连接得有多快,服务器端程序也可能因为处理大量同步请求而陷于停滞,甚至完全中断。无论如何,作为一个开发者,你希望控制用户等待多长的时间来获得应用的响应。就我们所知,用户不愿意等待太长时间,超过几秒钟通常被认为是不可接受的。
本hack在显示友好的信息给用户前花10秒钟等待服务器响应。
提示:如果你愿意,可以是5秒或更少,或者60秒。最大可容忍的等待时间依赖于你的应用场景、你的用户测试结果,以及其他因素。例如,比起依赖于应用并对其投入大量时间的局域网用户,一个普通的公众客户可能更希望一个活跃的应用,不愿意花时间等待。
本hack使用顶层window对象的名为setTimeout()的JavaScript方法。
提示:感谢Joshua Gitlin及他在http://www.xml.com/ pub/a/2005/05/11/ajax-error.html所发表的文章,它给本技术提供了很好的提示。
你可以不需要在前面冠以window对象而使用window对象的方法。换句话说,只使用setTimeout()和使用window.setTimeout()一样能正常工作。
setTimeout()接收一个函数名或者函数体作为第一个参数,另一个参数是调用方法前要等待的毫秒数(千分之一秒)。它返回一个数字值,这个数字值能用于取消函数调用。待会儿将会为你展示这些;同时,这里有段代码http_request.js,它封装了XMLHttpRequest对象的初始化以及用法。(“使用自己的库封装XMLHttpRequest”[Hack #3]可见更完整的解释。)
下面就是代码,重新改进以包含setTimeout()和一个新函数timesUp():var request = null;var timeoutId;/* request对象的封装函数。 参数: reqType: HTTP请求类型,如GET 或 POST。 url: 服务器端程序的URL asynch: 是否异步发送请求 respHandle: 处理响应的函数名 arguments[4]所代表的第5个参数是POST请求要发送的数据 */function httpRequest(reqType,url,asynch,respHandle){ //基于Mozilla的浏览器 if(window.XMLHttpRequest){ request = new XMLHttpRequest(); } else if (window.ActiveXObject){ request=new ActiveXObject("Msxml2.XMLHTTP"); if (! request){ request=new ActiveXObject("Microsoft.XMLHTTP"); }}//如果ActiveXObject没有被初始化,我们会测试到一个null的request if(request) { //如果请求类型是POST,那么第5个参数是被发送的数据 if(reqType.toLowerCase() != "post") { initReq(reqType,url,asynch,respHandle); } else { //被发送的数据 var args = arguments[4]; if(args != null && args.length > 0){ initReq(reqType,url,asynch,respHandle,args); } } } else { alert("Your browser does not permit the use of all "+ "of this application's features!"); }}/*初始化已经构造的request对象 */function initReq(reqType,url,bool,respHandle){ try{ /*指定处理HTTP响应的函数 */ request.onreadystatechange=respHandle; request.open(reqType,url,bool); timeoutId = setTimeout(timesUp,10000); //如果请求类型是POST,那么第5个参数是被发送的数据 if(reqType.toLowerCase() == "post") { request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); request.send(arguments[4]); } else { request.send(null); } } catch (errv) { alert( "The application cannot contact "+ "the server at the moment. "+ "Please try again in a few seconds.\n"+ "Error detail: "+errv.message); }}function timesUp(){//见下...request.open()方法为发起一个HTTP连接准备了XMLHttpRequest对象。然后代码在请求被发送之前调用setTimeout()。下面是余下的代码:/* XMLHttpRequest的事件处理器;这个函数并不是http_request.js的一部分,但是将被定义在另一个使用http_request.js的代码文件里,就像在httpRequest("GET",url,true,handleReq)一样 */function handleReq(){ if(request.readyState == 4){ //timeoutId 在http_request.js中声明 //但在这儿能作为一个全局变量引用 clearTimeout(timeoutId); if(request.status == 200){ //做些有趣的事... } }//结束外部的if}function timesUp(){ request.abort(); alert("A problem occurred with communicating with "+ "the server program. Please make sure you are connected "+ "to the Internet and try again in a few moments.");}