Ajax 如何将笨拙的 Web 界面转化成能迅速响应的 Ajax 应用程序。
ajax功能
就是不需要刷新整个页面就可以更新数据,不用像以前一样所有负担都压在服务器上,实现与后端的数据获取。
Ajax 用 JavaScript 把 XMLHttpRequest 对象放在 Web 表单和服务器之间。
当填写表单时,数据》》》》 JavaScript 代码 (不是 直接发送给服务器) 。
相反,JavaScript 代码捕获表单数据》》》》》服务器发送请求。
JavaScript 代码在幕后发送请求,用户甚至不知道请求的发出。更好的是,请求是异步发送的,就是说 JavaScript 代码(和用户)不用等待服务器的响应。
XMLHttpRequest 对象
XMLHttpRequest 对象,它是 Ajax 应用程序的中心,负责处理服务器端应用程序和脚本的请求,并处理从服务器端组件返回的数据。所以所有的 Ajax 应用程序都要使用 XMLHttpRequest 对象
创建新的 XMLHttpRequest 对象
<script language="javascript" type="text/javascript">
var xmlHttp = new XMLHttpRequest();
</script>
兼容性问题
var xmlHttp = false;
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
xmlHttp = false;
}
}
if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
xmlHttp = new XMLHttpRequest();
}
用 JavaScript 代码捕获和设置字段值
document.getElementById("oneId").value;
so 要用到 DOM
启动一个 Ajax 过程
<form>
<p>City: <input type="text" name="city" id="city" size="25"
onChange="callServer();" /></p>
</form>
当用户在 city 或 state 字段中输入新的值时,callServer() 方法就被触发,于是 Ajax 开始运行了。
发出请求
Ajax 采用一种沙箱安全模型。因此,Ajax 代码(具体来说就是 XMLHttpRequest 对象)只能对所在的同一个域发送请求,不能跨域。在本地机器上运行的代码只能对本地机器上的服务器端脚本发送请求。如果让 Ajax 代码在 http://www.breakneckpizza.com/ 上运行,则必须 http://www.breakneck.com/ 中运行的脚本发送请求。
设置服务器 URL
首先要确定连接的服务器的 URL。这并不是 Ajax 的特殊要求,但仍然是建立连接所必需的,显然现在你应该知道如何构造 URL 了。多数应用程序中都会结合一些静态数据和用户处理的表单中的数据来构造该 URL。
1、从 Web 表单中获取需要的数据。
2、建立要连接的 URL。
3、打开到服务器的连接。
4、设置服务器在完成后要运行的函数。
5、发送请求。
function callServer() {
//使用基本 JavaScript 代码获取几个表单字段的值
var city = document.getElementById("city").value;
var state = document.getElementById("state").value;
if ((city == null) || (city == "")) return;
if ((state == null) || (state == "")) return;
//设置一个 PHP 脚本作为链接的目标
var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);
// 连接方法(GET) 要连接的 URL true表示请求一个异步连接(这就是 Ajax 的由来)。false就要等服务器返回结果
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
escape() 方法,它用于转义不能用明文正确发送的任何字符。
document.write(escape("Visit W3School.com.cn!") + "<br />")
可以根据需要添加任意多个参数。比如,如果需要增加另一个参数,只需要将其附加到 URL 中并用 “与”(&)字符分开 [第一个参数用问号(?)和脚本名分开]。
打开请求
有了要连接的 URL 后就可以配置请求了。可以用 XMLHttpRequest 对象的 open() 方法来完成。该方法有五个参数:
1.request-type:发送请求的类型。典型的值是 GET 或 POST,
2.url:要连接的 URL。
3.asynch:如果希望使用异步连接则为 true,否则为 false。该参数是可选的,默认为 true。
4.username:如果需要身份验证,则可以在此指定用户名。该可选参数没有默认值。
5.password:如果需要身份验证,则可以在此指定口令。该可选参数没有默认值。
send(null)
因为需要的数据已经在url里了所以就为null;
处理响应
现在要面对服务器的响应了。现在只要知道两点:
什么也不要做,直到 xmlHttp.readyState 属性的值等于 4。
服务器将把响应填充到 xmlHttp.responseText 属性中。
第二点,使用 xmlHttp.responseText 属性获得服务器的响应,
function updatePage() {
if (xmlHttp.readyState == 4) {
//如果是就绪状态,则使用服务器返回的值设置另一个表单字段的值。
var response = xmlHttp.responseText;
document.getElementById("zipCode").value = response;
}
}
指定回调方法
首先一定要理解这些代码中的流程。建立其请求然后发出请求。此外,因为是异步请求,所以 JavaScript 方法(例子中的 getCustomerInfo())不会等待服务器。因此代码将继续执行,就是说,将退出该方法而把控制返回给表单。用户可以继续输入信息,应用程序不会等待服务器。
这就提出了一个有趣的问题:服务器完成了请求之后会发生什么?答案是什么也不发生,至少对现在的代码而言如此!显然这样不行,因此服务器在完成通过 XMLHttpRequest 发送给它的请求处理之后需要某种指示说明怎么做。
需要特别注意的是该属性在代码中设置的位置 —— 它是在调用 send() 之前 设置的。发送请求之前必须设置该属性,这样服务器在回答完成请求之后才能查看该属性。现在剩下的就只有编写 updatePage() 方法了,这是本文最后一节要讨论的重点。
处理服务器响应
服务器查看 onreadystatechange 属性确定要调用的方法,让用户访问另一个 URL 或者做响应服务器需要的任何事情。
回调和 Ajax
现在我们已经看到如何告诉服务器完成后应该做什么:将 XMLHttpRequest 对象的 onreadystatechange 属性设置为要运行的函数名。这样,当服务器处理完请求后就会自动调用该函数。也不需要担心该函数的任何参数。我们从一个简单的方法开始,
回调方法的代码
<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
//在 JavaScript 中引用函数:
JavaScript 是一种弱类型的语言,可以用变量引用任何东西。因此如果声明了一个函数 updatePage(),JavaScript 也将该函数名看作是一个变量。换句话说,可用变量名 updatePage 在代码中引用函数。
request.send(null);
}
function updatePage() {
alert("Server is done!");
}
</script>
它仅仅发出一些简单的警告,告诉你服务器什么时候完成了任务。在自己的网页中试验这些代码,然后在浏览器中打开输入电话号码然后离开该字段,将看到一个弹出的警告窗口,但是点击 OK 又出现了……
根据浏览器的不同,在表单停止弹出警告之前会看到两次、三次甚至四次警告。这是怎么回事呢?原来我们还没有考虑 HTTP 就绪状态,这是请求/响应循环中的一个重要部分。
HTTP 就绪状态
前面提到,服务器在完成请求之后会在 XMLHttpRequest 的 onreadystatechange 属性中查找要调用的方法。这是真的,但还不完整。事实上,每当 HTTP 就绪状态改变时它都会调用该方法。这意味着什么呢?首先必须理解 HTTP 就绪状态。
HTTP 就绪状态表示请求的状态或情形。它用于确定该请求是否已经开始、是否得到了响应或者请求/响应模型是否已经完成。它还可以帮助确定读取服务器提供的响应文本或数据是否安全。在 Ajax 应用程序中需要了解五种就绪状态:
. 0:请求没有发出(在调用 open() 之前)。
·1:请求已经建立但还没有发出(调用 send() 之前)。
·2:请求已经发出正在处理之中(这里通常可以从响应得到内容头部)。
·3:请求已经处理,响应中通常有部分数据可用,但是服务器还没有完成响应。
·4:响应已完成,可以访问服务器响应并使用它。
查看就绪状态
function updatePage() {
// Output the current ready state
alert("updatePage() called with ready state of " + request.readyState);
}
对于 Ajax 编程,需要直接处理的惟一状态就是就绪状态 4,它表示服务器响应已经完成,可以安全地使用响应数据了。基于此,回调方法中的第一行应该如
检查就绪状态
function updatePage() {
if (request.readyState == 4)
alert("Server is done!");
}
修改后就可以保证服务器的处理已经完成。尝试运行新版本的 Ajax 代码,现在就会看到与预期的一样,只显示一次警告信息了。
可以在就绪状态发生变化时更新页面。
例如,对于就绪状态 1 来说要将进度指示器的宽度设置为 25%,对于就绪状态 2 来说要将进度指示器的宽度设置为 50%,对于就绪状态 3 来说要将进度指示器的宽度设置为 75%,当就绪状态为 4 时将进度指示器的宽度设置为 100%(完成)。
HTTP 状态码
·401:未经授权
·403:禁止
·404:没找到
.200:一切正常
重定向和重新路由
—— 重定向。在 HTTP 状态代码中,这是 300 系列的状态代码,包括:
·301:永久移动
·302:找到(请求被重新定向到另外一个 URL/URI 上)
·305:使用代理(请求必须使用一个代理来访问所请求的资源)
因此除了就绪状态外,还需要检查 HTTP 状态。我们期望的状态码是 200,它表示一切顺利。如果就绪状态是 4 而且状态码是 200,就可以处理服务器的数据了,而且这些数据应该就是要求的数据(而不是错误或者其他有问题的信息)。因此还要在回调方法中增加状态检查.
检查 HTTP 状态码
function updatePage() {
if (request.readyState == 4)
if (request.status == 200)
alert("Server is done!");
}
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);
}
读取响应文本
现在可以确保请求已经处理完成(通过就绪状态4),服务器给出了正常的响应(通过状态码200),最后我们可以处理服务器返回的数据了。返回的数据保存在 XMLHttpRequest 对象的 responseText 属性中。
关于 responseText 中的文本内容,比如格式和长度,有意保持含糊。这样服务器就可以将文本设置成任何内容。比方说,一种脚本可能返回逗号分隔的值,另一种则使用管道符(即 | 字符)分隔的值,还有一种则返回长文本字符串。何去何从由服务器决定。
在本文使用的例子中,服务器返回客户的上一个订单和客户地址,中间用管道符分开。然后使用订单和地址设置表单中的元素值,
function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "");
}
else
alert("status is " + request.status);
}
}
JavaScript split() 方法从管道符分开。得到的数组放到 response 中。数组中的第一个值用 response[0] 访问,被设置为 ID 为 “order” 的字段的值。第二个值 response[1],即客户地址,则需要更多一点处理。因为地址中的行用一般的行分隔符(“\n”字符)分隔,代码中需要用 XHTML 风格的行分隔符 <br /> 来代替。替换过程使用 replace() 函数和正则表达式完成。最后,修改后的文本作为 HTML 表单 div 中的内部 HTML。结果就是表单突然用客户信息更新了,
使用 Ajax 生成一个 HEAD 请求
function getSalesData() {
createRequest();
var url = "/boards/servlet/UpdateBoardSales";
request.open("HEAD", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
当生成一个 HEAD 请求时,服务器并不会像对 GET 或 POST 请求一样返回一个真正的响应。相反,服务器只会返回资源的 头(header),这包括响应中内容最后修改的时间、请求资源是否存在和很多其他有用信息。可以在服务器处理并返回资源之前使用这些信息来了解有关资源的信息。
对于这种请求可以做的最简单的事情就是简单地输出所有的响应头的内容。这可以让你了解通过 HEAD 请求可以使用什么
输出从 HEAD 请求中获得的响应头的内容
function updatePage() {
if (request.readyState == 4) {
alert(request.getAllResponseHeaders());
}
}
检查 URL(没毛线用)
有用的 HEAD 请求
你会发现 HEAD 请求非常有用的一个领域是用来查看内容的长度或内容的类型。这样可以确定是否需要发回大量数据来处理请求,和服务器是否试图返回二进制数据,而不是 HTML、文本或 XML(在 JavaScript 中,这 3 种类型的数据都比二进制数据更容易处理)。
在这些情况中,你只使用了适当的头名,并将其传递给 XMLHttpRequest 对象的 getResponseHeader() 方法。因此要获取响应的长度,只需要调用 request.getResponseHeader("Content-Length");。要获取内容类型,请使用 request.getResponseHeader("Content-Type");。
在很多应用程序中,生成 HEAD 请求并没有增加任何功能,甚至可能会导致请求速度变慢(通过强制生成一个 HEAD 请求来获取有关响应的数据,然后在使用一个 GET 或 POST 请求来真正获取响应)。然而,在出现你不确定有关脚本或服务器端组件的情况时,使用 HEAD 请求可以获取一些基本的数据,而不需要对响应数据真正进行处理,也不需要大量的带宽来发送响应。
利用 DOM 进行 Web 响应
..............................
..............................
..............................
这个太大了,我也说不全 自己尝试吧