传送门:异步编程系列目录……
示例源码:触碰jQuery:AJAX异步详解.rar
AJAX 全称 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。它并非一种新的技术,而是以下几种原有技术的结合体。
1) 使用CSS和XHTML来表示。
2) 使用DOM模型来交互和动态显示。
3) 使用XMLHttpRequest来和服务器进行异步通信。
4) 使用javascript来绑定和调用。
通过AJAX异步技术,可以在客户端脚本与web服务器交互数据的过程中使用XMLHttpRequest对象来完成HTTP请求(Request)/应答(Response)模型:
1) 不需要用户等待服务端响应。在异步派发XMLHttpRequest请求后控制权马上就被返回到浏览器。界面不会出现白板,在得到服务器响应之前还可以友好的给出一个加载提示。
2) 不需要重新加载整个页面。为XMLHttpRequest注册一个回调函数,待服务器响应到达时,触发回调函数,并且传递所需的少量数据。“按需取数据”也降低了服务器的压力。
3) 不需要使用隐藏或内嵌的框架。在XHR对象之前,模拟Ajax通信通常使用hack手段,如使用隐藏的或内嵌的框架(
下面介绍下AJAX中的重要对象:XMLHttpRequest。
XMLHttpRequest对象(XHR)
XMLHttpRequest是一套可以在Javascript、VbScript、Jscript等脚本语言中通过http协议传送或接收XML及其他数据的一套API。
XMLHttpRequest对象首次以ActiveX对象形式在微软Internet Explorer(IE) 5中以引入。其他浏览器制造商在认识到这一对象重要性后也纷纷实现了XMLHttpRequest对象,但是以一个本地JavaScript对象而不是作为一个ActiveX对象实现。而如今,由于安全性、标准等问题,微软已经在其IE 7中把XMLHttpRequest实现为一个本地JavaScript对象。
API |
描述 |
||||||||||||||
客服端请求 |
|||||||||||||||
open(method,url,async, bstrUser, bstrPassword) |
规定请求的类型、URL 以及是否异步处理请求。 1) method:请求的类型,例如:POST、GET、PUT及PROPFIND。大小写不敏感。 2) url:请求的URL地址,可以为绝对地址也可以为相对地址。 3) async[可选]:true(默认,异步)或 false(同步)。 注释:当您使用async=false 时,JavaScript 会等到服务器响应就绪才继续执行。如果服务器繁忙或缓慢,应用程序会挂起或停止。此时,不需要编写onreadystatechange回调函数,把代码放到 send()语句后面即可。 4) bstrUser[可选]:如果服务器需要验证,此处指定用户名,如果未指定,当服务器需要验证时,会弹出验证窗口。 5) bstrPassword[可选]:验证信息中的密码部分,如果用户名为空,则此值将被忽略。 |
||||||||||||||
getRequestHeader(name) |
获取指定的相应头部信息 |
||||||||||||||
setRequestHeader(name,value) |
自定义HTTP头部信息。需在open()方法之后和send()之前调用,才能成功发送请求头部信息。 传送门:HTTP 头部详解
默认情况下,服务器对POST请求和提交Web表单不会一视同仁,将Content-Type头部信息设置为application/x-www-form-urlencoded (模拟表单提交) |
||||||||||||||
send(string) |
将请求发送到服务器。参数string仅用于POST请求;对于GET请求的参数写在url后面,所以string参数传递null。 |
||||||||||||||
abort() |
调用此方法可取消异步请求,调用后,XHR对象停止触发事件,不允许访问任何与响应相关的属性; |
||||||||||||||
服务端响应 |
|||||||||||||||
onreadystatechange事件 |
对于异步请求,如果需要对服务器获取和操作响应结果,则在send() 之前,需要为onreadystatechange属性指定处理方法。该函数用于对服务器响应进行处理。 |
||||||||||||||
readyState |
存有XMLHttpRequest的状态。每当readyState改变时,就会触发onreadystatechange事件。 从 0 到 4 发生变化:
|
||||||||||||||
status(数字表示) |
返回当前请求的http状态码。 传送门:HTTP状态码一览表(HTTP Status Code)
|
||||||||||||||
statusText(字符表示) |
返回当前请求的状态文本eg:OK (status:200) |
||||||||||||||
responseText |
将响应信息作为字符串返回 |
||||||||||||||
responseXML |
将响应信息格式化为Xml Document对象并返回 |
||||||||||||||
responseBody(只有微软的IE支持) |
将响应信息正文以unsigned byte数组形式返回(二进制数据) |
||||||||||||||
responseStream(只有IE的某些版本支持) |
以Ado Stream对象(二进制流)的形式返回响应信息 |
||||||||||||||
getResponseHeader(name) |
从响应信息中获取指定的http头 |
||||||||||||||
getAllResponseHeaders() |
获取响应的所有http头 |
||||||||||||||
overrideMimeType |
通常用于重写服务器响应的MIME类型。Eg,正常情况下XMLHttpRequest只接收文本数据,但我们可以重写MIME为“text/plain; charset=x-user-defined”,以欺骗浏览器避免浏览器格式化服务器返回的数据,以实现接收二进制数据。 |
一个简单的ajax封装:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
var
myAjax = {
// XMLHttpRequest IE7+, Firefox, Chrome, Opera, Safari ; ActiveXObject IE6, IE5
xhr: window.XMLHttpRequest ?
new
XMLHttpRequest() :
new
ActiveXObject(
'Microsoft.XMLHTTP'
),
get:
function
(url, callback) {
this
.xhr.open(
'get'
, url);
this
.onreadystatechange(callback,
this
.xhr);
this
.xhr.send(
null
);
},
post:
function
(url, data, callback) {
this
.xhr.open(
'post'
, url);
this
.xhr.setRequestHeader(
'Content-Type'
,
'application/x-www-form-urlencoded'
);
this
.onreadystatechange(callback,
this
.xhr);
this
.xhr.send(data);
},
onreadystatechange:
function
(func, _xhr) {
_xhr.onreadystatechange =
function
() {
if
(_xhr.readyState == 4) {
if
(_xhr.status == 200) {
func(_xhr.responseText);
}
}
}
}
}
|
使用:
1
2
3
4
5
6
7
8
9
|
$(
'#btn_nowTime1'
).bind(
'click'
,
null
,
function
() {
myAjax.post(
'AjaxHandler.ashx'
,
'func=GetServerTime'
,
function
(data) {
if
(data)
alert(data);
}
);
});
|
XMLHttpRequest Level 2
XMLHttpRequest是一个浏览器接口,使得Javascript可以进行 HTTP (S) 通信。但是,这个接口一直没有标准化,每家浏览器的实现或多或少有点不同。HTML 5 的概念形成后,W3C 开始考虑标准化这个接口。2008年 2 月,提出了XMLHttpRequest Level 2 草案。
1. 老版本的缺点
老版本的XMLHttpRequest对象有以下几个缺点:
1) 只支持文本数据的传送,无法用来读取和上传二进制文件。
2) 传送和接收数据时,没有进度信息,只能提示有没有完成。
3) 受到"同域限制"(Same Origin Policy),只能向同一域名的服务器请求数据。
2. 新版本的功能
新版本的XMLHttpRequest对象,针对老版本的缺点,做出了大幅改进。
1) 可以设置 HTTP 请求的时限。
2) 可以使用FormData对象管理表单数据。
3) 可以上传文件。
4) 可以请求不同域名下的数据(跨域资源共享,Cross-origin resource sharing,简称 CORS)。
5) 可以获取服务器端的二进制数据。
6) 可以获得数据传输的进度信息。
3. 介绍几个XMLHttpRequest Leve2 新增的成员
超时时限 |
|
timeout |
设置ajax请求超时时限,过了这个时限,就自动停止 HTTP请求。 |
ontimeout事件 |
当ajax超过timeout 时限时触发的回调函数。 |
指定响应格式 |
|
responseType |
(默认:“text”)在发送请求前,根据您的数据需要,将xhr.responseType设置为“text”、“arraybuffer”、“blob”或“document”。 |
response |
成功发送请求后,xhr的响应属性会包含DOMString、ArrayBuffer、Blob 或 Document 形式(具体取决于responseTyp的设置)的请求数据。 |
进度信息 |
|
progress 事件 |
在XMLHttpRequest对象传递数据的时候用来返回进度信息。它分成上传和下载两种情况。下载的 progress 事件属于XMLHttpRequest对象,上传的 progress 事件属于XMLHttpRequest.upload对象。即: xhr.onprogress = updateProgress; xhr.upload.onprogress = updateProgress; XHR还新增了与progress事件相关的五个事件: 1) load 事件:传输成功完成。 2) abort 事件:传输被用户取消。 3) error 事件:传输中出现错误。 4) loadstart事件:传输开始。 5) loadEnd事件:传输结束,但是不知道成功还是失败。 |
4. 一个新功能实例
1) 接收二进制数据(方法A:改写MIMEType)
老版本的XMLHttpRequest对象,只能从服务器取回文本数据。但我们可以改写数据的MIMEType,将服务器返回的二进制数据伪装成文本数据,并且告诉浏览器这是用户自定义的字符集。
关键代码如下:
服务端
1
2
3
4
5
6
7
8
9
10
11
|
String str =
"二进制数据获取"
;
MemoryStream _memory =
new
MemoryStream();
BinaryFormatter formatter =
new
BinaryFormatter();
formatter.Serialize(_memory, str);
_memory.Position = 0;
byte
[] read =
new
byte
[_memory.Length];
_memory.Read(read, 0, read.Length);
_memory.Close();
context.Response.ContentType =
"text/plain"
;
// 服务器使用OutputStream输出二进制流
context.Response.OutputStream.Write(read, 0, read.Length);
|
客服端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
$(
'#btn_mime'
).bind(
'click'
,
null
,
function
() {
$.ajax(
'AjaxHandler.ashx?func=GetBinaryData'
,
{
type:
'get'
,
dataType:
'text'
,
cache:
false
,
mimeType:
'text/plain; charset=x-user-defined'
,
success:
function
(data) {
if
(data) {
var
byte = [];
for
(
var
i = 0, len = data.length; i < len; ++i) {
var
c = data.charCodeAt(i);
byte[byte.length] = c & 0xff;
}
alert(byte);
}
}
});
});
|
浏览器会把相应数据当做文本数据接收,所以我们还必须再一个个字节地还原成二进制数据。位运算"c & 0xff",表示在每个字符的两个字节之中,只保留后一个字节,将前一个字节扔掉。原因是浏览器解读字符的时候,会把字符自动解读成Unicode 的 0xF700-0xF7ff区段。
截图如下:(测试环境:google Chrome 版本 26.0.1410.43)
服务器端返回二进制数据:
客服端输出:
a) 使用mimeType: 'text/plain; charset=x-user-defined'参数。
b) 没有对服务器的MIME类型进行重写,导致返回信息被浏览器格式化后输出的二进制数据与服务器不同。并且不同浏览器格式化后输出的二进制数据都有差异。
2) 接收二进制数据(方法B:responseType属性)
在XMLHttpRequest Level2中,可以使用新增的responseType属性从服务器取回二进制数据。把responseType设为 blob,表示服务器传回的是二进制对象。
1
2
3
|
var
xhr =
new
XMLHttpRequest();
xhr.open (
'GET'
,
'/path/to/image.png'
);
xhr.responseType =
'blob'
;
|
接收数据的时候,用浏览器自带的 Blob 对象即可。注意,读取的xhr.response,而不是xhr.responseText。
1
|
var
blob =
new
Blob ([xhr.response], {type:
'image/png'
});
|
还可以将responseType设为arraybuffer,把二进制数据装在一个数组里。然后再遍历这个数组。
1
2
3
4
5
6
7
8
9
10
|
var
xhr =
new
XMLHttpRequest ();
xhr.open (
'GET'
,
'/path/to/image.png'
);
xhr.responseType =
"arraybuffer"
;
var
arrayBuffer = xhr.response;
if
(arrayBuffer) {
var
byteArray =
new
Uint8Array (arrayBuffer);
for
(vari = 0; i
// do something
}
}
|
5. 更多XMLHttpRequest Level 2新功能描述请看:
1) XMLHttpRequest 增强功能
2) XMLHttpRequest Level 2 使用指南
3) XMLHttpRequest2 新技巧
jQuery框架的Ajax
jQuery是一个快速、简单的JavaScript library,核心理念是write less,do more(写的更少,做的更多)。它简化了HTML 文件的traversing,事件处理、动画、Ajax 互动,从而方便了网页制作的快速发展。jQuery是为改变你编写JavaScript 的方式而设计的。更多jQuery科普知识请看:jQuery百度百科(Eg:模块,历史版本)
下面介绍下jQuery框架中ajax相关API:
版本Jquery-1.7.1.js。
1. jQuery.ajax( [url,] options )
通过 HTTP 请求加载远程数据。
返回值:$.ajax() 返回jqXHR对象(jqXHR对象:为XMLHttpRequest对象的超集)。可用于手动终止请求abort()、为ajax函数设置额外的回调函数等。
ajax内部实现的两个重要对象:s对象和jqXHR对象。
1) s对象
由默认设置jQuery.ajaxSettings对象、options参数集合和jQuery.ajaxSetup({})默认设置合并而成s对象。
参数名 |
描述 |
|||||||||||||
可由ajax的options参数设置 |
||||||||||||||
url |
(默认: 当前页地址) 要请求的目的URL地址。 |
|||||||||||||
username password |
用于响应HTTP访问认证请求的用户名及密码 |
|||||||||||||
type |
(默认: "GET") 请求方式 ("POST" 或 "GET")。注意:其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。 |
|||||||||||||
dataType |
预期服务器返回的数据类型。如果不指定,jQuery将自动根据 HTTP 包 MIME 信息来智能判断,比如 XML MIME 类型就被识别为 XML。随后服务器端返回的数据会根据这个值解析后,传递给回调函数。 必须确保网页服务器报告的 MIME 类型与我们选择的dataType所匹配。比如说,XML的话,服务器端就必须声明 text/xml 或者 application/xml 来获得一致的结果。 可用值:
其中,text 和 xml 类型返回的数据不会经过处理。数据仅仅简单的将XMLHttpRequest的responseText或responseHTML属性传递给 success 回调函数。 如果指定了 script 或者jsonp类型,那么当从服务器接收到数据时,实际上是用了 你可能感兴趣的:(jquery,javascript) |