AJAX学习
AJAX技术背景介绍
Ajax(Asynchronous JavaScript + XML)不是一种技术。实际上,它由几种蓬勃发展的技术以新的强大方式组合而成。Ajax包含:
1. 基于CSS标准的表示;
2. 使用Document Object Model(DOM对象)进行动态显示和交互;
3. 使用XMLHttpRequest与服务器进行异步通信;
4. 使用JavaScript绑定一切。
Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。
传统的Web应用模型与应用Ajax技术的界面:
传统Web应用的同步交互过程和Ajax应用的异步交互过程的比较
XMLHttpRequest慨述
在使用XMLHttpRequest对象发送请求和处理响应之前,必须先用JavaScript创建一个XMLHttpRequest对象。由于XMLHttpRequest不是一个W3C标准,所以可以采用多种方法使用JavaScript来创建XMLHttpRequest的实例。Internet Explorer把XMLHttpRequest实现为一个ActiveX对象,其他浏览器(如Firefox、Safari和Opera)把它实现为一个本地JavaScript对象。由于存在这些差别,JavaScript代码中必须包含有关的逻辑,从而使用ActiveX技术或者使用本地JavaScript对象技术来创建XMLHttpRequest的一个实例。
很多人可能还记得从前的那段日子,那时不同浏览器上的JavaScript和DOM实现简直千差万别,听了上面这段话之后,这些人可能又会不寒而栗。幸运的是,在这里为了明确该如何创建XMLHttpRequest对象的实例,并不需要那么详细地编写代码来区别浏览器类型。你要做的只是检查浏览器是否提供对ActiveX对象的支持。如果浏览器支持ActiveX对象,就可以使用ActiveX来创建XMLHttpRequest对象。否则,就要使用本地JavaScript对象技术来创建。下面代码展示了编写跨浏览器的JavaScript代码来创建XMLHttpRequest对象实例是多么简单。
创建XMLHttpRequest对象的一个实例
var xmlHttp;
function createXMLHttpRequest() {
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
}
可以看到,创建XMLHttpRequest对象相当容易。首先,要创建一个全局作用域变量xmlHttp来保存这个对象的引用。createXMLHttpRequest方法完成创建XMLHttpRequest实例的具体工作。这个方法中只有简单的分支逻辑(选择逻辑)来确定如何创建对象。对window.ActiveXObject的调用会返回一个对象,也可能返回null,if语句会把调用返回的结果看作是true或false(如果返回对象则为true,返回null则为false),以此指示浏览器是否支持ActiveX控件,相应地得知浏览器是不是Internet Explorer。如果确实是,则通过实例化ActiveXObject的一个新实例来创建XMLHttpRequest对象,并传入一个串指示要创建何种类型的ActiveX对象。在这个例子中,为构造函数提供的字符串是Microsoft.XMLHTTP,这说明你想创建XMLHttpRequest的一个实例。
如果window.ActiveXObject调用失败(返回null),JavaScript就会转到else语句分支,确定浏览器是否把XMLHttpRequest实现为一个本地JavaScript对象。如果存在window.
XMLHttpRequest,就会创建XMLHttpRequest的一个实例。
由于JavaScript具有动态类型特性,而且XMLHttpRequest在不同浏览器上的实现是兼容的,所以可以用同样的方式访问XMLHttpRequest实例的属性和方法,而不论这个实例创建的方法是什么。这就大大简化了开发过程,而且在JavaScript中也不必编写特定于浏览器的逻辑。
Ajax核心:XMLHTTP组件相关技术资料
数据库远程管理技术
基于互联网的广域网现代应用中的一个重要环节是数据库远程监控。首先简单回顾一下互联网上的数据库远程管理技术的发展过程和方式:
1、早期通过编写CGI-BIN程序模块进行数据库远程管理。但CGI-BIN的运行速度慢,维护很不方便,现在已经基本被弃用。
2、这几年使用组件对象模型(Component Object Model, COM)的应用非常多,效果也很好。但如果使用的是第三方服务器,服务器方往往因为保密或其它商业原因不允许用户注册自己的组件。
3、近年来由微软公司推出的.NET平台和SUN公司的J2EE平台都是非常高档的数据库远程管理与服务平台。都能提供优质的多层(n-Tier)应用服务。 其中,.NET的简单对象访问协议(Simple Object Access Protocol, SOAP)使用超文本传输协议(Hypertext Transfer Protocol, HTTP)和扩展标记语言(Extensible Markup Language, XML)技术实现跨系统(例如Windows - Linux)的通讯服务方式已经广为开发商接受和使用。许多大型应用,例如企业资源计划(Enterprise resource planning, ERP)等都建立在这样的大型平台之上。 但对于中小型应用,比如一个网站的建设和维护,这种大型应用平台就显得有些尾大不掉,开销也过于庞大。
曾经在互联网技术和Java技术方面一度落后的微软公司在XML应用开发则走在了前头。她的XML解析器(MSXML)中的XMLHTTP协议是一个非常方便实用的客户/服务通讯管道。综合运用XMLHTTP以及ActiveX数据对象(ActiveX Data Objects, ADO/ADOX)可以简单方便地实现数据库远程管理。
数据库远程管理体系
数据库远程管理的任务流程是:
1、客户端向服务端发出数据库结构和数据的查询或修改指令。
2、服务端接受并执行有关指令并向客户端返回结果。
3、客户端接受并显示服务端返回的指令执行结果。
实现数据库远程管理的二个主要关键环节是:
1、客户端与服务端之间的指令上传和结果下传的数据通道,由XMLHTTP协议实现。
2、服务端前沿与数据库之间的指令传送和结果返回,由起着中间层作用的ADO/ADOX接口完成。
XMLHTTP的使用
顾名思义,XMLHTTP是个传送XML格式数据的超文本传输协议。实际上,XMLHTTP的数据传输过程更为灵活一些,它上传的指令可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。还可以是URL的参数。 它下达的结果可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。
客户端调用XMLHTTP的过程很简单,只有5个步骤:
1、创建XMLHTTP对象
2、打开与服务端的连接,同时定义指令发送方式,服务网页(URL)和请求权限等。
客户端通过Open命令打开与服务端的服务网页的连接。与普通HTTP指令传送一样,可以用"GET"方法或"POST"方法指向服务端的服务网页。
3、发送指令。
4、等待并接收服务端返回的处理结果。
5、释放XMLHTTP对象
一、XMLHTTP方法
Open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword )
bstrMethod:数据传送方式,即GET或POST。
bstrUrl:服务网页的URL。
varAsync:是否同步执行。缺省为True,即同步执行,但只能在DOM中实施同步执行。应用中一般将其置为False,即异步执行。
bstrUser:用户名,可省略。
bstrPassword:用户口令,可省略。
Send( varBody )
varBody:指令集。可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。也可以省略(null),让指令通过Open方法的URL参数代入。
setRequestHeader ( bstrHeader, bstrValue )
bstrHeader:HTTP 头(header)
bstrValue:HTTP 头(header)的值
如果Open方法定义为POST,可以定义表单方式上传xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
二、XMLHTTP属性
onreadystatechange:在同步执行方式下获得返回结果的事件句柄。只能在DOM中调用。
responseBody:结果返回为无符号整数数组。
responseStream:结果返回为IStream流。
responseText :结果返回为字符串。
responseXML:结果返回为XML格式数据。
三、HTTP 就绪状态
前面提到,服务器在完成请求之后会在 XMLHttpRequest 的 onreadystatechange 属性中查找要调用的方法。这是真的,但还不完整。事实上,每当 HTTP 就绪状态改变时它都会调用该方法。首先必须理解 HTTP 就绪状态。HTTP 就绪状态表示请求的状态或情形。它用于确定该请求是否已经开始、是否得到了响应或者请求/响应模型是否已经完成。它还可以帮助确定读取服务器提供的响应文本或数据是否安全。在 Ajax 应用程序中需要了解五种就绪状态:
• 0:请求没有发出(在调用 open() 之前)。
• 1:请求已经建立但还没有发出(调用 send() 之前)。
• 2:请求已经发出正在处理之中(这里通常可以从响应得到内容头部)。
• 3:请求已经处理,响应中通常有部分数据可用,但是服务器还没有完成响应。
• 4:响应已完成,可以访问服务器响应并使用它。
演示代码:
function updatePage() {
if (request.readyState == 4)
alert("Server is done!");
}
四、HTTP 状态码
因此除了就绪状态外,还需要检查 HTTP 状态。我们期望的状态码是 200,它表示一切顺利。如果就绪状态是 4 而且状态码是 200,就可以处理服务器的数据了,而且这些数据应该就是要求的数据(而不是错误或者其他有问题的信息)。因此还要在回调方法中增加状态检查
演示代码:
function updatePage() {
if (request.readyState == 4)
if (request.status == 200)
alert("Server is done!");
else if (request.status == 404)
alert("Request URL does not exist");
else
alert("Error: status code is " + request.status);
}
AJAX的问题
半数以上的AJAX安全风险来自隐含在服务器中的漏洞。显然,使用安全编码技术的好的设计,对于更安全的AJAX大有帮助,我们需要感谢Max熟悉开放万维网应用安全计划(the Open Web Application Security Project - OWASP)排名前十的最严重web应用程序安全漏洞列表。不幸的是,当Max实现AJAX的时候,他仍然需要面对许多额外的因素:
1.新的技术:如果想把站点连接到一个SQL数据库,在Google查到了数百万的例子。AJAX技术,不管这种技术有多年轻,它仍然是出现在采购循环中相对较早的,尽管它只有很少一部分好的例子出现在网络上。为了解决一些难处理的和不必要的复杂问题,这就要求开发者去自主开发。不得不编写服务器端和客户端的代码,创建他自己不太确定的协议(特别是对服务器响应来讲)。不管这些协议有多好,都将会及时表现在页面上。
2.非传统方式的设计:AJAX有一点点不同于传统设计方式,因为这样的应用程序是半客户端半服务端的。所以开发者为服务端和客户端都能够进行编码。在同一时间使用两种不同的语言(特别是在早期阶段)进行开发将会产生一些初级的编码错误,因为开发者要在两端来回跳跃,对一端来讲非常好,但可能在另一端不能够胜任。即使开发者有一个大的开发团队,安全编码责任也可能在服务端和客户端开发小组之间代码移交的时候发生问题。
3.太多的脚本语言:开发者凭借他自己的聪明才智决定建立世界上最优秀的旅行登记工具。你从输入你现在的位置(通过邮政编码、电话区号或者GPS等等)开始登记,这时候一个AJAX请求就会被立即发送来确定你确切的位置。从那时候开始,屏幕上就会填入你所有可以利用的旅行方式,这一切甚至都是在你决定你想要去什么地方、你打算什么时候动身和你打算和谁一同去之前就完成的。
这个屏幕上的单元格和控件都充满了AJAX驱动,服务器端和客户端的脚本可能需要超过20个不同的服务器调用。你可以想像一个很小的个体服务器程序,比如findairportsbylocation.aspx 或者 determinemaxbaggageallowancebyairline.php.
显而易见,如果没有开发者的仔细计划(比如创建多功能的“重载”JavaScript函数和服务器脚本),每一次设计他都需要创建超过40个独立的部分。更多的编程意味着会产生更多的错误和bug,意味着需要更多的时间去编写、管理、测试和更新代码。不仅如此,因为在客户端的JavaScript代码中应用了大量的这种脚本,他们在正式的程序测试中也容易变得很健忘。
4.确定小部分的AJAX不会引起危害:这个站点是一个计划出行的站点,但是Max考虑的是它将立刻为你提供一个显示精确位置的卫星视图,并且把你所要到达目的地的天气情况也提供给你。AJAX最大的诱惑之一看起来好像是直到最后一刻它还在进行其它的操作,就像一个讲解员在那里解说一样,为了AJAX使用了AJAX。当Max开始尝试他的新想法时,他会逐渐尝试增加更多新的功能,完全忽视测试的需要。
5.不安全的通讯:每一个AJAX调用可能只回传很少数量的数据给客户端,但那些数据是私有的、保密的。开发者可以编写一个便利的工具来对你的信用卡号码进行数字校验,但是如果使用纯文本代替over SSL进行发送数据会怎样呢?这是一个显而易见的问题,但是当有许多例行程序需要考虑,特别是屏幕上其它99%的数据不是真正的机密数据时,很容易就会忽视掉SSL的。
6.服务器端访问控制:使用JavaScript程序来触发AJAX经常会掩饰一些显而易见的编码错误,服务器端访问控制就是一个例子。假设开发者想参考你上次游览的一个详细目的地来为你提供你中意的旅馆,他可能会是像下面这样:
showprevioushotels.aspx?userid=12345&destination=UK
这当然是非常好的,但是如果一个恶意用户把URL改成了如下所示该怎么办呢:
showprevioushotels.aspx?userid=12346&destination=%
他们会得到其他人最喜爱的旅馆吗?(注意:%在SQL语句中是通配符)。无疑,这是一个没有什么危害的例子,但是开发者应该使用session、cookie或者其它符号形式来确保数据能并且只能发送到正确的用户那里。它们可能仅仅是数据的一小部分,但它们可能就是最重要的一小部分。
7.服务器端验证:实际上这里有两个问题。第一,AJAX控制经常被用来在用户最后提交到服务器之前的输入验证。因为这是一个服务器端的检查,当这个页面最后被提交的时候他不必再次为在服务器上做检查而烦恼,这里我们假定不会有恶意的用户暗中破坏从alloweddestinations.php的响应或者破坏对服务器最后的请求。
AJAX控制可以比用户自己更仔细验证用户的输入,但是他们还是经常在服务器上最后做一次验证。
AJAX验证的第二个问题就是控制本身会受到验证漏洞的影响。这里再次强调一下,URL通常是隐藏着的,所以也会经常忘掉它。举例说明一下,也许我可以使用SQL Injection来对刚才的脚本进行攻击,如下所示:
showprevioushostels.aspx?userid='; update users set type='admin' where userid=12345;--
就会让我登录后具有系统管理员的权限。当然,如何取得那些表名(table)和字段名已经超出了本文讨论的范围,但是你已经了解这种情况了,不是吗?
8.客户端验证:我们已经知道在刚才的Google Suggest例子中,通过简单评测服务端的响应后动态创建和执行JavaScript函数是可行的。如果没有任何形式的验证(如果这样的话在客户端很难保证可靠性和流畅性),客户端将仅仅简单执行服务器需要它完成的事情。
AJAX安全提示
1、为了取得成功,你必须从好的计划开始。必须集中你的才智减少和简化AJAX调用,创建一个标准的响应格式,在任何地方都要遵循这个协定(理想的XML)。
2、遵循来自像开放万维网应用安全计划那样的站点的最优方法。这里面特别包含了访问控制和输入校验漏洞检查,同时确保敏感信息使用over SSL胜过使用普通文本。
3、永远不要假设服务器端AJAX对于访问控制或者用户输入校验检查能够代替在服务器上的最终再检查。增加AJAX控制永远不会减少你的验证工作量,它们只能增加你的工作量。
4、永远不要假设客户端的混淆技术(obfuscation,在这里指使JavaScript难于阅读和解码)能够保护你非常重要的商业秘密。使用JavaScript是隐藏程序设计最没用的一种手段,还能够为你的对手提供好处。
5、最后,你必须非常好的领导你的开发团队。
AJAX技术背景介绍
Ajax(Asynchronous JavaScript + XML)不是一种技术。实际上,它由几种蓬勃发展的技术以新的强大方式组合而成。Ajax包含:
1. 基于CSS标准的表示;
2. 使用Document Object Model(DOM对象)进行动态显示和交互;
3. 使用XMLHttpRequest与服务器进行异步通信;
4. 使用JavaScript绑定一切。
Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。
传统的Web应用模型与应用Ajax技术的界面:
传统Web应用的同步交互过程和Ajax应用的异步交互过程的比较
XMLHttpRequest慨述
在使用XMLHttpRequest对象发送请求和处理响应之前,必须先用JavaScript创建一个XMLHttpRequest对象。由于XMLHttpRequest不是一个W3C标准,所以可以采用多种方法使用JavaScript来创建XMLHttpRequest的实例。Internet Explorer把XMLHttpRequest实现为一个ActiveX对象,其他浏览器(如Firefox、Safari和Opera)把它实现为一个本地JavaScript对象。由于存在这些差别,JavaScript代码中必须包含有关的逻辑,从而使用ActiveX技术或者使用本地JavaScript对象技术来创建XMLHttpRequest的一个实例。
很多人可能还记得从前的那段日子,那时不同浏览器上的JavaScript和DOM实现简直千差万别,听了上面这段话之后,这些人可能又会不寒而栗。幸运的是,在这里为了明确该如何创建XMLHttpRequest对象的实例,并不需要那么详细地编写代码来区别浏览器类型。你要做的只是检查浏览器是否提供对ActiveX对象的支持。如果浏览器支持ActiveX对象,就可以使用ActiveX来创建XMLHttpRequest对象。否则,就要使用本地JavaScript对象技术来创建。下面代码展示了编写跨浏览器的JavaScript代码来创建XMLHttpRequest对象实例是多么简单。
创建XMLHttpRequest对象的一个实例
var xmlHttp;
function createXMLHttpRequest() {
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
}
可以看到,创建XMLHttpRequest对象相当容易。首先,要创建一个全局作用域变量xmlHttp来保存这个对象的引用。createXMLHttpRequest方法完成创建XMLHttpRequest实例的具体工作。这个方法中只有简单的分支逻辑(选择逻辑)来确定如何创建对象。对window.ActiveXObject的调用会返回一个对象,也可能返回null,if语句会把调用返回的结果看作是true或false(如果返回对象则为true,返回null则为false),以此指示浏览器是否支持ActiveX控件,相应地得知浏览器是不是Internet Explorer。如果确实是,则通过实例化ActiveXObject的一个新实例来创建XMLHttpRequest对象,并传入一个串指示要创建何种类型的ActiveX对象。在这个例子中,为构造函数提供的字符串是Microsoft.XMLHTTP,这说明你想创建XMLHttpRequest的一个实例。
如果window.ActiveXObject调用失败(返回null),JavaScript就会转到else语句分支,确定浏览器是否把XMLHttpRequest实现为一个本地JavaScript对象。如果存在window.
XMLHttpRequest,就会创建XMLHttpRequest的一个实例。
由于JavaScript具有动态类型特性,而且XMLHttpRequest在不同浏览器上的实现是兼容的,所以可以用同样的方式访问XMLHttpRequest实例的属性和方法,而不论这个实例创建的方法是什么。这就大大简化了开发过程,而且在JavaScript中也不必编写特定于浏览器的逻辑。
Ajax核心:XMLHTTP组件相关技术资料
数据库远程管理技术
基于互联网的广域网现代应用中的一个重要环节是数据库远程监控。首先简单回顾一下互联网上的数据库远程管理技术的发展过程和方式:
1、早期通过编写CGI-BIN程序模块进行数据库远程管理。但CGI-BIN的运行速度慢,维护很不方便,现在已经基本被弃用。
2、这几年使用组件对象模型(Component Object Model, COM)的应用非常多,效果也很好。但如果使用的是第三方服务器,服务器方往往因为保密或其它商业原因不允许用户注册自己的组件。
3、近年来由微软公司推出的.NET平台和SUN公司的J2EE平台都是非常高档的数据库远程管理与服务平台。都能提供优质的多层(n-Tier)应用服务。 其中,.NET的简单对象访问协议(Simple Object Access Protocol, SOAP)使用超文本传输协议(Hypertext Transfer Protocol, HTTP)和扩展标记语言(Extensible Markup Language, XML)技术实现跨系统(例如Windows - Linux)的通讯服务方式已经广为开发商接受和使用。许多大型应用,例如企业资源计划(Enterprise resource planning, ERP)等都建立在这样的大型平台之上。 但对于中小型应用,比如一个网站的建设和维护,这种大型应用平台就显得有些尾大不掉,开销也过于庞大。
曾经在互联网技术和Java技术方面一度落后的微软公司在XML应用开发则走在了前头。她的XML解析器(MSXML)中的XMLHTTP协议是一个非常方便实用的客户/服务通讯管道。综合运用XMLHTTP以及ActiveX数据对象(ActiveX Data Objects, ADO/ADOX)可以简单方便地实现数据库远程管理。
数据库远程管理体系
数据库远程管理的任务流程是:
1、客户端向服务端发出数据库结构和数据的查询或修改指令。
2、服务端接受并执行有关指令并向客户端返回结果。
3、客户端接受并显示服务端返回的指令执行结果。
实现数据库远程管理的二个主要关键环节是:
1、客户端与服务端之间的指令上传和结果下传的数据通道,由XMLHTTP协议实现。
2、服务端前沿与数据库之间的指令传送和结果返回,由起着中间层作用的ADO/ADOX接口完成。
XMLHTTP的使用
顾名思义,XMLHTTP是个传送XML格式数据的超文本传输协议。实际上,XMLHTTP的数据传输过程更为灵活一些,它上传的指令可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。还可以是URL的参数。 它下达的结果可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。
客户端调用XMLHTTP的过程很简单,只有5个步骤:
1、创建XMLHTTP对象
2、打开与服务端的连接,同时定义指令发送方式,服务网页(URL)和请求权限等。
客户端通过Open命令打开与服务端的服务网页的连接。与普通HTTP指令传送一样,可以用"GET"方法或"POST"方法指向服务端的服务网页。
3、发送指令。
4、等待并接收服务端返回的处理结果。
5、释放XMLHTTP对象
一、XMLHTTP方法
Open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword )
bstrMethod:数据传送方式,即GET或POST。
bstrUrl:服务网页的URL。
varAsync:是否同步执行。缺省为True,即同步执行,但只能在DOM中实施同步执行。应用中一般将其置为False,即异步执行。
bstrUser:用户名,可省略。
bstrPassword:用户口令,可省略。
Send( varBody )
varBody:指令集。可以是XML格式数据,也可以是字符串,流,或者一个无符号整数数组。也可以省略(null),让指令通过Open方法的URL参数代入。
setRequestHeader ( bstrHeader, bstrValue )
bstrHeader:HTTP 头(header)
bstrValue:HTTP 头(header)的值
如果Open方法定义为POST,可以定义表单方式上传xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
二、XMLHTTP属性
onreadystatechange:在同步执行方式下获得返回结果的事件句柄。只能在DOM中调用。
responseBody:结果返回为无符号整数数组。
responseStream:结果返回为IStream流。
responseText :结果返回为字符串。
responseXML:结果返回为XML格式数据。
三、HTTP 就绪状态
前面提到,服务器在完成请求之后会在 XMLHttpRequest 的 onreadystatechange 属性中查找要调用的方法。这是真的,但还不完整。事实上,每当 HTTP 就绪状态改变时它都会调用该方法。首先必须理解 HTTP 就绪状态。HTTP 就绪状态表示请求的状态或情形。它用于确定该请求是否已经开始、是否得到了响应或者请求/响应模型是否已经完成。它还可以帮助确定读取服务器提供的响应文本或数据是否安全。在 Ajax 应用程序中需要了解五种就绪状态:
• 0:请求没有发出(在调用 open() 之前)。
• 1:请求已经建立但还没有发出(调用 send() 之前)。
• 2:请求已经发出正在处理之中(这里通常可以从响应得到内容头部)。
• 3:请求已经处理,响应中通常有部分数据可用,但是服务器还没有完成响应。
• 4:响应已完成,可以访问服务器响应并使用它。
演示代码:
function updatePage() {
if (request.readyState == 4)
alert("Server is done!");
}
四、HTTP 状态码
因此除了就绪状态外,还需要检查 HTTP 状态。我们期望的状态码是 200,它表示一切顺利。如果就绪状态是 4 而且状态码是 200,就可以处理服务器的数据了,而且这些数据应该就是要求的数据(而不是错误或者其他有问题的信息)。因此还要在回调方法中增加状态检查
演示代码:
function updatePage() {
if (request.readyState == 4)
if (request.status == 200)
alert("Server is done!");
else if (request.status == 404)
alert("Request URL does not exist");
else
alert("Error: status code is " + request.status);
}
AJAX的问题
半数以上的AJAX安全风险来自隐含在服务器中的漏洞。显然,使用安全编码技术的好的设计,对于更安全的AJAX大有帮助,我们需要感谢Max熟悉开放万维网应用安全计划(the Open Web Application Security Project - OWASP)排名前十的最严重web应用程序安全漏洞列表。不幸的是,当Max实现AJAX的时候,他仍然需要面对许多额外的因素:
1.新的技术:如果想把站点连接到一个SQL数据库,在Google查到了数百万的例子。AJAX技术,不管这种技术有多年轻,它仍然是出现在采购循环中相对较早的,尽管它只有很少一部分好的例子出现在网络上。为了解决一些难处理的和不必要的复杂问题,这就要求开发者去自主开发。不得不编写服务器端和客户端的代码,创建他自己不太确定的协议(特别是对服务器响应来讲)。不管这些协议有多好,都将会及时表现在页面上。
2.非传统方式的设计:AJAX有一点点不同于传统设计方式,因为这样的应用程序是半客户端半服务端的。所以开发者为服务端和客户端都能够进行编码。在同一时间使用两种不同的语言(特别是在早期阶段)进行开发将会产生一些初级的编码错误,因为开发者要在两端来回跳跃,对一端来讲非常好,但可能在另一端不能够胜任。即使开发者有一个大的开发团队,安全编码责任也可能在服务端和客户端开发小组之间代码移交的时候发生问题。
3.太多的脚本语言:开发者凭借他自己的聪明才智决定建立世界上最优秀的旅行登记工具。你从输入你现在的位置(通过邮政编码、电话区号或者GPS等等)开始登记,这时候一个AJAX请求就会被立即发送来确定你确切的位置。从那时候开始,屏幕上就会填入你所有可以利用的旅行方式,这一切甚至都是在你决定你想要去什么地方、你打算什么时候动身和你打算和谁一同去之前就完成的。
这个屏幕上的单元格和控件都充满了AJAX驱动,服务器端和客户端的脚本可能需要超过20个不同的服务器调用。你可以想像一个很小的个体服务器程序,比如findairportsbylocation.aspx 或者 determinemaxbaggageallowancebyairline.php.
显而易见,如果没有开发者的仔细计划(比如创建多功能的“重载”JavaScript函数和服务器脚本),每一次设计他都需要创建超过40个独立的部分。更多的编程意味着会产生更多的错误和bug,意味着需要更多的时间去编写、管理、测试和更新代码。不仅如此,因为在客户端的JavaScript代码中应用了大量的这种脚本,他们在正式的程序测试中也容易变得很健忘。
4.确定小部分的AJAX不会引起危害:这个站点是一个计划出行的站点,但是Max考虑的是它将立刻为你提供一个显示精确位置的卫星视图,并且把你所要到达目的地的天气情况也提供给你。AJAX最大的诱惑之一看起来好像是直到最后一刻它还在进行其它的操作,就像一个讲解员在那里解说一样,为了AJAX使用了AJAX。当Max开始尝试他的新想法时,他会逐渐尝试增加更多新的功能,完全忽视测试的需要。
5.不安全的通讯:每一个AJAX调用可能只回传很少数量的数据给客户端,但那些数据是私有的、保密的。开发者可以编写一个便利的工具来对你的信用卡号码进行数字校验,但是如果使用纯文本代替over SSL进行发送数据会怎样呢?这是一个显而易见的问题,但是当有许多例行程序需要考虑,特别是屏幕上其它99%的数据不是真正的机密数据时,很容易就会忽视掉SSL的。
6.服务器端访问控制:使用JavaScript程序来触发AJAX经常会掩饰一些显而易见的编码错误,服务器端访问控制就是一个例子。假设开发者想参考你上次游览的一个详细目的地来为你提供你中意的旅馆,他可能会是像下面这样:
showprevioushotels.aspx?userid=12345&destination=UK
这当然是非常好的,但是如果一个恶意用户把URL改成了如下所示该怎么办呢:
showprevioushotels.aspx?userid=12346&destination=%
他们会得到其他人最喜爱的旅馆吗?(注意:%在SQL语句中是通配符)。无疑,这是一个没有什么危害的例子,但是开发者应该使用session、cookie或者其它符号形式来确保数据能并且只能发送到正确的用户那里。它们可能仅仅是数据的一小部分,但它们可能就是最重要的一小部分。
7.服务器端验证:实际上这里有两个问题。第一,AJAX控制经常被用来在用户最后提交到服务器之前的输入验证。因为这是一个服务器端的检查,当这个页面最后被提交的时候他不必再次为在服务器上做检查而烦恼,这里我们假定不会有恶意的用户暗中破坏从alloweddestinations.php的响应或者破坏对服务器最后的请求。
AJAX控制可以比用户自己更仔细验证用户的输入,但是他们还是经常在服务器上最后做一次验证。
AJAX验证的第二个问题就是控制本身会受到验证漏洞的影响。这里再次强调一下,URL通常是隐藏着的,所以也会经常忘掉它。举例说明一下,也许我可以使用SQL Injection来对刚才的脚本进行攻击,如下所示:
showprevioushostels.aspx?userid='; update users set type='admin' where userid=12345;--
就会让我登录后具有系统管理员的权限。当然,如何取得那些表名(table)和字段名已经超出了本文讨论的范围,但是你已经了解这种情况了,不是吗?
8.客户端验证:我们已经知道在刚才的Google Suggest例子中,通过简单评测服务端的响应后动态创建和执行JavaScript函数是可行的。如果没有任何形式的验证(如果这样的话在客户端很难保证可靠性和流畅性),客户端将仅仅简单执行服务器需要它完成的事情。
AJAX安全提示
1、为了取得成功,你必须从好的计划开始。必须集中你的才智减少和简化AJAX调用,创建一个标准的响应格式,在任何地方都要遵循这个协定(理想的XML)。
2、遵循来自像开放万维网应用安全计划那样的站点的最优方法。这里面特别包含了访问控制和输入校验漏洞检查,同时确保敏感信息使用over SSL胜过使用普通文本。
3、永远不要假设服务器端AJAX对于访问控制或者用户输入校验检查能够代替在服务器上的最终再检查。增加AJAX控制永远不会减少你的验证工作量,它们只能增加你的工作量。
4、永远不要假设客户端的混淆技术(obfuscation,在这里指使JavaScript难于阅读和解码)能够保护你非常重要的商业秘密。使用JavaScript是隐藏程序设计最没用的一种手段,还能够为你的对手提供好处。
5、最后,你必须非常好的领导你的开发团队。