Ajax(一)——javascript实现

Ajax技术已经广泛运用到如今的web开发中,它将一部分服务器承担的工作转移到客户端,减轻服务器的压力,无刷新更新页面的方式提高了用户体验,并且通过调用XML等外部数据进一步促进了页面显示和数据的分离。下文将从Ajax入手,总结javascript中的一些基础知识。

Ajax的基本原理

在浏览器和服务器之间加了一个中间层——Ajax引擎,使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,一些数据验证交由Ajax引擎处理,需要从服务器获取数据时再由Ajax引擎向服务器提出请求。

XMLHttpRequest是Ajax最核心的概念,在使用XMLHttpRequest对象发送请求和处理响应之前,首先应该初始化Ajax对象。由于XMLHttpRequest不是W3C标准,所以不同浏览器中初始化该对象的方法是不同的。主要分为两大类:

IE浏览器

IE中使用ActiveXObject对象,而针对IE的不同版本又有不同实例化的方法,这篇文章里讲的很详细了,戳Using the right version of MSXML in Internet Explorer

1
var xmlhttprequest = new ActiveXObject("Msxml2.XMLHTTP.3.0");

1
var xmlhttprequest = new ActiveXObject("Msxml2.XMLHTTP.6.0");

1
var xmlhttprequest = new ActiveXObject("Microsoft.XMLHTTP");
非IE浏览器

包括Chrome、Firefox等

1
var xmlhttprequest = new XMLHttpRequest();

XMLHttpRequest对象的常用属性

1、指定状态改变时触发事件的处理函数:onreadystatechange
1
2
3
4
xmlhttprequest.onreadystatechange = onReadyStateChange;
function onReadyStateChange() {
//do something
}

通过上面的代码实现当指定状态改变时触发的onReadyStateChange函数,可能已经注意到onReadyStateChange后面没有括号,那么

element.onclick = funcName; 与 element.onclick = funcName();的区别是什么呢?

以点击事件为例,后者为调用方式,当点击操作产生的时候,该函数会立刻执行,有返回值的话会将函数的返回值返回给onclick;前者为引用方式,只是传递了函数体所在的地址,在需要的时候才会执行指向的函数体。

2、获取请求状态属性:
readystate值 描述
0 未初始化(已经创建一个XMLHttpRequest对象,还未调用open方法)
1 正在加载(已经调用open()方法,已经准备好把一个请求发送到服务器)
2 已加载(已经通过send()方法把一个请求发送到服务器端,但是还没有收到一个响应)
3 交互中(已经接收到HTTP响应头部信息,但是消息体部分还没有完全接收结束)
4 完成(接收到全部数据)

在实际应用中,该属性经常用于判断请求状态,当请求状态为4,即请求完成了,再根据服务器端返回的状态码来判断请求时候成功。

3、获取服务器返回HTTP状态属性:status

这里列出的只是部分常用的HTTP状态码,全部的请参考http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

  • 1xx:信息
  • 2xx:成功
  • 3xx:重定向
  • 4xx:客户端错误
  • 5xx:服务器端错误
状态码 标志 含义
200 OK 请求成功
204 No Content 服务器成功处理了请求,但没有返回任何内容
301 Moved Permanently 所请求页面已转移至新地址
302 Moved Temporarily 所请求页面临时转到了新的地址
400 Bad Request 服务器不理解请求
403 Forbidden 页面禁止访问
404 Not Found 服务器找不到所请求的页面
408 Request Timeout 请求所用时间超出服务器等待时间
500 Internal Server Error 服务器遇到异常情况
504 Gateway Timeout 网关超时

结合2、3点可以判断请求是否成功,从而执行返回数据等操作

1
2
3
if(xmlhttprequest.readyState == 4) {
alert(xmlhttprequest.status == 200 ? "请求成功" : "请求失败");
}
4、获取服务器返回响应文本的属性:responseText

通常采用

1
var content = xmlhttprequest.responseText;

的形式获取服务器端返回的文本(字符串),将返回的信息当成字符串使用。

如果返回的是XML,则通过responseXML属性获得,即

1
var content = xmlhttprequest.responseXML;

XMLHttpRequest对象的常用方法

1、创建请求:open

open方法用于设置请求的url、请求方法以及其它参数信息

open(method, url [,async, username, password])

  • method:请求HTTP的方法,通常为GET、POST
  • url:请求地址
  • async:可选参数,用于指定请求方式,默认异步true;如果设为同步false,后续对send()的调用将阻塞,直到响应完全接收。
  • username和password同样为可选参数,为url所需的授权提供认证。
2、设置HTTP请求头:setRequestHeader

setRequestHeader(header, value)

  • header:设置头部的名称
  • value:指定头部的值

setRequestHeader() 方法指定了一个 HTTP 请求的头部,用在open()之后,send()之前。例如,使用POST的方法时候,需要设置Content-Type请求头的值 为”application/x-www-form-urlencode”

setRequestHeader("Content-Type", "application/x-www-form-urlencode");

3、发送请求:send

send(content)

如果请求的方法为POST,则content为post的数据;请求方法为GET的话,content则设置为null

4、返回HTTP头信息:getResponseHeader与getResponseHeaders

getResponseHeader(header)

  • header:用于指定HTTP头,可以为Server、Content-Type、Date等。
  • getResponseHeaders()

以字符串的形式返回完整的HTTP头信息,包括Server、Content-Type、Date、Content-Length。

Ajax示例

HTML页面中有一个文本框,失去焦点的时候执行testAjax()方法,传入两个参数,一个是请求的url,另一个是请求的method。

1
2
3
4
<form name="form" method="post" action="">
<input type="name" value="" onblur="testAjax('ajax.html','GET');">
<input type="submit" onclick="return check();">
</form>

check函数

1
2
3
4
function check() {
//do some check
return CHECK通过 ? true : false;
}

onclick = “check();” 与 onclick = “return check();”的区别?

javascript在事件中调用函数时用return返回值实际上是对window.event.returnvalue进行设置,而该值决定了当前操作时候继续,true继续,false中断;不用return返回值时则会默认地继续执行操作。

testAjax方法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function testAjax(url, method, content) {
var xmlhttprequest = getXmlHttpRequestObject();//实例XMLHttpRequest对象
xmlhttprequest.onreadystatechange = onReadyStateChange;//状态改变触发函数
xmlhttprequest.open(method, url, true);
//POST方法时候需要设置Content-Type
if (method == "POST") {
xmlhttprequest.setRequestHeader("Content-Type", "application/x-www-form-urlencode");
}
xmlhttprequest.send(content);
function getXmlHttpRequestObject() {
var xmlhttprequest = null;
//非IE
if(window.XMLHttpRequest) {
xmlhttprequest = new XMLHttpRequest();
} else if(window.ActiveXObject) {
try {
xmlhttprequest = new ActiveXObject("Msml2.XMLHTTP.3.0");
} catch(e) {
try {
xmlhttprequest = new ActiveXObject("Msml2.XMLHTTP.6.0");
} catch(e) {
try {
xmlhttprequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return;
}
}
}
}
return xmlhttprequest;
}
function onReadyStateChange() {
//请求已发送,并且请求成功
if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200) {
alert(xmlhttprequest.responseText);//请求结果
}
}
}

function funcName(){} 、 function(){}; 、 (function(){})() 的区别?

第一个是比较常见的定义javascript函数的方法,二三是javascript中的匿名函数。
event = function(){};这种方式常用于定义一个DOM元素事件处理函数,不会设置具体函数的名字,而是让它的对应事件引用匿名函数。
(function(){})(),小括号把表达式组合分块,并且每一块都有一个返回值,也就是表达式中小括号的返回值。当用小括号把匿名函数括起来的时候,实际上小括号返回的是一个匿名函数的Function对象,就如同有名字的函数取得它的引用位置了。所以,此时在后面再加上一对小括号是参数列表,就会实现普通函数的调用形式。

javscript中这样设置参数默认值可以吗? function funcName(a = 0){alert(a);}

在Firefox下正常,Chrome下控制台里可以看到Uncaught SyntaxError: Unexpected token =
也就是说上述设置默认参数的方式不是兼容的,如果需要设置默认参数应该怎么做呢?例如,设置默认的访问方式为POST
var method = arguments[1] ? arguments[1] : "POST";
javascript中预设arguments存储参数的数组,函数的所有参数都将按顺序保存在数组中,下标从0开始,所以method为arguments[1]。
var method = method || "POST";
与第一种类似,是一种javascript支持的人更加简洁的方式。
var method = (typeof method !== 'undefined') ? method : "POST";
当调用未传值时,method是undefined的,所以采用先判断类型,再执行三元操作符。


参考资料

Just a beginner.<br /><a href='https://github.com/yaoshanliang/about' target='_blank'>profile</a>