使用JS和Ajax发出异步请求本文介绍了如何创建能够适应不同浏览器的XMLHttpRequest实例,建立和发送请求,并响应服务器。您将开始接触最基本和基础性的有关Ajax的全部对象和编程方法:XMLHttpRequest对象。该对象实际上仅仅是一个跨越所有Ajax应用程序的公共线程,您可能已经预料到,只有彻底理解该对象才能充分发挥编程的潜力。XMLHttpRequest简介XMLHttpRequest是JS的一个对象。它是介绍Web2.0、Ajax和大部分其他内容的核心。下面给出该对象的几个方法和属性:1、open():建立到服务器的新请求。2、send():向服务器发送请求。3、abort():退出当前请求。4、readyState:提供当前HTML的就绪状态。5、responseText:服务器返回的请求响应文本。用XMLHttpRequest能够做什么呢,值得注意的是这些方法和属性都与发送请求及处理响应有关。事实上,如果看到XMLHttpRequest的所有方法和属性,就会发现它们都与非常简单的请求/响应模型有关。用好该对象可以彻底改变您的应用程序。创建XMLHttpRequest对象实例首先需要创建一个新变量并赋给它一个XMLHttpRequest对象实例。这在JS中很简单,只要对该对象名使用new关键字即可.创建新的XMLHttpRequest对象:varrequest=newXMLHttpRequest();创建XMLHttpRequest的Java伪代码:XMLHttpRequestrequest=newXMLHttpRequest();错误与跨浏览器处理在实际上各种事情都可能出错,而上面的代码没有提供任何错误处理。较好的办法是创建该对象,并在出现问题时优雅地退出。比如,任何较早的浏览器都不支持XMLHttpRequest,您需要让这些用户知道有些地方出了问题。下面说明如何创建该对象,以便在出现问题的时候发出JavaScript警告。创建具有错误处理能力的XMLHttpRequest对象scriptlanguage=javascripttype=text/javascriptvarrequest=false;try{request=newXMLHttpRequest();}catch(failed){request=false;}if(!request)alert(ErrorinitializingXMLHttpRequest!);/script一定要理解这些步骤:1、创建一个新变量request并赋值false。后面将使用false作为判定条件,它表示还没有创建XMLHttpRequest对象。2、增加try/catch块:3、尝试创建XMLHttpRequest对象。4、如果失败(catch(failed))则保证request的值仍然为false。5、检查request是否仍为false(如果一切正常就不会是false)。6、如果出现问题(request是false)则使用JavaScript警告通知用户出现了问题。现在已经得到了一段带有错误检查的XMLHttpRequest对象创建代码,还可以告诉您哪儿出了问题。增加对Microsoft浏览器的支持scriptlanguage=javascripttype=text/javascriptvarrequest=false;try{request=newXMLHttpRequest();}catch(trymicrosoft){try{request=newActiveXObject(Msxml2.XMLHTTP);}catch(othermicrosoft){try{request=newActiveXObject(Microsoft.XMLHTTP);}catch(failed){request=false;}}}if(!request)alert(ErrorinitializingXMLHttpRequest!);/script下面分别介绍每一步:1、创建一个新变量request并赋值false。使用false作为判断条件,它表示还没有创建XMLHttpRequest对象。2、增加try/catch块:3、尝试创建XMLHttpRequest对象。4、检查request是否仍然为false(如果一切顺利就不会是false)。5、如果出现问题(request是false)则使用JavaScript警告通知用户出现了问题。这样修改代码之后再使用InternetExplorer试验,就应该看到已经创建的表单(没有错误消息)。静态代码与动态代码代码都直接嵌套在script标记中,不放到方法或函数体中的JS代码称为静态JS。这种情况代码是在页面显示给用户之前的某个时候运行。虽然根据规范不能完全精确地知道这些代码何时运行对浏览器有什么影响,但是可以保证这些代码在用户能够与页面交互之前运行,这也是多数Ajax程序员创建XMLHttpRequest对象的一般方式。将XMLHttpRequest创建代码移动到方法中scriptlanguage=javascripttype=text/javascriptvarrequest;functioncreateRequest(){try{request=newXMLHttpRequest();}catch(trymicrosoft){try{request=newActiveXObject(Msxml2.XMLHTTP);}catch(othermicrosoft){try{request=newActiveXObject(Microsoft.XMLHTTP);}catch(failed){request=false;}}}if(!request)alert(ErrorinitializingXMLHttpRequest!);}/script如果按照这种方式编写代码,那么在处理Ajax之前需要调用该方法。因此还需要使用XMLHttpRequest的创建方法。functiongetCustomerInfo(){createRequest();}此方式惟一的问题是推迟了错误通知,这也是多数Ajax程序员不采用这一方法的原因。如果使用静态JS,用户在点击页面的时候很快就会看到错误信息。这样也很烦人,是不是?可能令用户错误地认为您的Web应用程序不能在他的浏览器上运行。不过,当然要比他们花费了10分钟输入信息之后再显示同样的错误要好。因此,我建议编写静态的代码,让用户尽可能早地发现问题。用XMLHttpRequest发送请求得到请求对象之后就可以进入请求/响应循环了。记住XMLHttpRequest惟一的目的是让您发送请求和接收响应。其他一切都是JS、CSS或页面中其他代码的工作。如改变用户界面、切换图像、解释服务器返回的数据。准备好XMLHttpRequest之后,就可以向服务器发送请求了。Ajax采用一种沙箱安全模型。因此Ajax代码(具体来说就是XMLHttpRequest对象)只能对所在的同一个域发送请求。记住:在本地机器上运行的代码只能对本地机器上的服务器端脚本发送请求。如让Ajax代码在上运行,则必须在中运行的脚本发送请求。设置服务器URL首先要确定连接的服务器的URL。这并不是Ajax的特殊要求,但仍然是建立连接所必需的,显然现在您应该知道如何构造URL了。多数应用程序中都会结合一些静态数据和用户处理的表单中的数据来构造该URL。建立请求URLscriptlanguage=javascripttype=text/javascriptvarrequest=false;try{request=newXMLHttpRequest();}catch(trymicrosoft){try{request=newActiveXObject(Msxml2.XMLHTTP);}catch(othermicrosoft){try{request=newActiveXObject(Microsoft.XMLHTTP);}catch(failed){request=false;}}}if(!request)alert(ErrorinitializingXMLHttpRequest!);functiongetCustomerInfo(){varphone=document.getElementById(phone).value;varurl=/cgi-local/lookupCustomer.php?phone=+escape(phone);}/script首先代码创建了一个新变量phone,并把ID为“phone”的表单字段的值赋给它。下面展示了这个表单的HTML,其中可以看到phone字段及其id属性。bodypimgsrc=breakneck-logo_4c.gifalt=BreakNeckPizza//pformaction=POSTpEnteryourphonenumber:inputtype=textsize=14name=phoneid=phoneonChange=getCustomerInfo();/span/ppYourorderwillbedeliveredto:/pdivid=address/divpTypeyourorderinhere:/pptextareaname=orderrows=6cols=50id=order/textarea/ppinputtype=submitvalue=OrderPizzaid=submit//p/form/body还要注意,当用户输入电话号码或者改变电话号码时,将触发getCustomerInfo()方法。该方法取得电话号码并构造存储在url变量中的URL字符串。记住,由于Ajax代码是沙箱型的,因而只能连接到同一个域,实际上URL中不需要域名。escape()方法是一个顶级JS方法,并不与任何对象关联。使用escape方法可以将属性值手工添加到URL中。escape方法编码指定字符串中的特定字符,并返回新字符串。它用于转义不能用明文正确发送的任何字符。比如电话号码中的空格将被转换成字符%20,从而能够在URL中传递这些字符。可以根据需要添加任意多个参数。比如需要增加另一个参数,只需要将其附加到URL中并用“与”(&)字符分开,第一个参数用问号(?)和脚本名分开。打开请求open()是打开吗?Internet开发人员对open()方法到底做什么没有达成一致。但它实际上并不是打开一个请求。如果监控HTML/Ajax页面及其连接脚本之间的网络和数据传递,当调用open()方法时将看不到任何通信。不清楚为何选用了这个名字,但显然不是一个好的选择。有了要连接的URL后就可以配置请求了。可以用XMLHttpRequest对象的open()方法来完成。该方法有五个参数:1、request-type:发送请求的类型。典型的值是GET或POST,但也可以发送HEAD请求。2、url:要连接的URL。3、asynch:如果希望使用异步连接则为true,否则为false。该参数是可选的,默认为true。4、username:如果需要身份验证,则可以在此指定用户名。该可选参数没有默认值。5、password:如果需要身份验证,则可以在此指定口令。该可选参数没有默认值。通常使用其中的前三个参数。事实上即使需要异步连接,也应该指定第三个参数为true。这是默认值,但坚持明确指定请求是异步的还是同步的更容易理解。functiongetCustomerInfo(){varphone=document.getElementById(phone).value;varurl=/cgi-local/lookupCustomer.p