触碰jQuery:AJAX异步详解(转)

Posted 会飞的鱼儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了触碰jQuery:AJAX异步详解(转)相关的知识,希望对你有一定的参考价值。

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手段,如使用隐藏的或内嵌的框架(<iframe>标签)。

下面介绍下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 头部详解

Accept

浏览器能够处理的媒体类型

Accept-Charset

浏览器申明自己接收的字符集

Accept-Encoding

浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)

Host

客户端指定要请求的WEB服务器的域名/IP 地址和端口号

Referer

发出请求的页面的URI

Content-Type

标明发送或者接收的实体的MIME类型。传送门:

1HTTP Content-type对照表

2格式:Content-Type: [type]/[subtype]; parameter

X-Requested-With

非标准HTTP头,只为firefox3标注是否为ajax异步请求,null表示为同步请求。

默认情况下,服务器对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 发生变化:

0(未初始化)

对象已建立,但是尚未初始化(尚未调用open方法)

1(初始化)

对象已建立,尚未调用send方法

2(发送数据)

send方法已调用,但是当前的状态及http头未知

3(数据传送中)

已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误

4(完成)

数据接收完毕,此时可以通过responseXml和responseText获取完整的回应数据

 

status(数字表示)

返回当前请求的http状态码。

传送门:HTTP状态码一览表(HTTP Status Code

1xx(临时响应)

表示临时响应并需要请求者继续执行操作的状态代码。

2xx (成功)

表示成功处理了请求的状态代码。Eg:200

3xx (重定向)

表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向。Eg:304

4xx(请求错误)

这些状态代码表示请求可能出错,导致服务器无法正常处理。Eg:404

5xx(服务器错误)

这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。Eg:500

 

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),只能向同一域名的服务器请求数据。

  1. 新版本的功能

新版本的XMLHttpRequest对象,针对老版本的缺点,做出了大幅改进。

1)   可以设置 HTTP 请求的时限。

2)   可以使用FormData对象管理表单数据。

3)   可以上传文件。

4)   可以请求不同域名下的数据(跨域资源共享,Cross-origin resource sharing,简称 CORS)。

5)   可以获取服务器端的二进制数据。

6)   可以获得数据传输的进度信息。

  1. 介绍几个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事件:传输结束,但是不知道成功还是失败。

  1. 一个新功能实例

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<byteArray.byteLength; i++) {
        // do something
    }
}
  1. 更多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 来获得一致的结果。

可用值:

"xml"

返回 XML 文档,可用jQuery处理。

"html"

返回纯文本 HTML 信息;包含的 script 标签会在插入dom时执行

"script"

返回纯文本 JavaScript 代码,常常用于跨域请求。不会触发全局事件和局部事件;只支持GET方式(POST请求会自动转化为GET请求);默认不启用缓存(cache:false)

"json"

返回 JSON 数据。JSON 数据是一种能很方便通过 JavaScript 解析的结构化数据。

"jsonp"

JSONP 格式,用于跨域请求。

"text"

返回纯文本字符串

其中,text 和 xml 类型返回的数据不会经过处理。数据仅仅简单的将XMLHttpRequest的responseText或responseHTML属性传递给 success 回调函数。

如果指定了 script 或者jsonp类型,那么当从服务器接收到数据时,实际上是用了<script>标签而不是XMLHttpRequest对象。这种情况下,$.ajax() 不再返回一个XMLHttpRequest对象,并且也不会传递事件处理函数,比如beforeSend。

contentType

(默认: "application/x-www-form-urlencoded")标明发送或者接收的实体的MIME类型。当非GET或HEAD请求的HTTP请求时,会被设置为HTTP头请求信息。

mimeType

多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions);用于重写服务器端响应的MIME类型。

data

发送到服务器的数据。可以是一个查询字符串,比如 key1=value1&amp;key2=value2 ,也可以是一个映射,比如 {key1: \'value1\', key2: \'value2\'} 。如果使用了后者的形式,则数据在发送前会通过jQuery.param()函数转换成查询字符串。这个处理过程也可以通过设置processData选项为false来回避。

processData

(默认: true) 默认情况下,发送到服务器的数据(即data参数)将被转换为字符串以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为false。

jQuery中的处理方式:

1
2
3
if ( s.data&&s.processData&&typeofs.data !== "string" ) {
    s.data = jQuery.param(s.data, s.traditional );
}

async

(默认: true) 默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。

timeout

设置请求超时时间(毫秒)。通过setTimeout(fn,time)实现。

cache

(默认: true)dataType为 script 和jsonp时默认为 false。设置为 false 将不缓存此页面。

当使用GET或HEAD方式发送请求时要添加时间戳参数 (net Date()).getTime() 来保证每次发送的URL不同, 可以避免浏览器缓存.(只有GET和HEAD方式的请求浏览器才会缓存

jQuery中的处理方式:

1
2
3
4
5
6
7
if ( s.cache === false ) {
    var ts = jQuery.now(),
    // rts = /([?&])_=[^&]*/尝试替换
    ret = s.url.replace( rts, "$1_=" + ts );
    // rquery = /\\?/如果没有替换任何内容,则把时间戳加到url最后
    s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
}

示例:/AjaxHandler.ashx?func=GetBinaryData&_=1368424995535

ifModified

(默认: false) 仅在服务器数据改变时获取新数据。通过响应头If-Modified-Since、IF-None-Match和请求头Last-Modified、Etag提高GET或HEAD方式请求效率。(只有GET和HEAD方式的请求浏览器才会缓存)

global

(默认: true) 是否触发全局 AJAX 事件。设置为 false 将不会触发全局AJAX 事件:ajaxStart、ajaxSend、ajaxSuccess、ajaxError、ajaxComplete、ajaxStop。(比如请求频繁时可禁用全局AJAX事件提高效率)

context

(默认:true)  这个对象用于设置Ajax相关回调函数的上下文,让回调函数内this指向这个对象。如果不设定这个参数,那么回调函数中的this就指向调用本次AJAX请求时传递的options参数载体“s对象”。但对于全局Ajax事件来说,this都是指向全局事件所绑定的元素。

jsonp

指定获得jsonp回调函数名的参数名(默认为:callback)。这个值用来替代URL中"callback=?"里的"callback"部分,比如{jsonp:\'onJsonPLoad\'}会替换为将"onJsonPLoad=?"传给服务器。

jsonpCallback

为jsonp请求指定一个回调函数名。jsonpCallback参数一般为字符串,也可接收函数(该函数返回字符串)。

默认情况下生成随机函数名:"jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, "" ) + jQuery.now()

crossDomain

(默认:null)false:同域请求;true跨域请求。

倘若crossDomain标识为null,则jQuery会自动根据本地url、端口来解析。可以根据需求直接赋值来提高性能。

通常情况下由服务器自动解析即可,但如果你想在同一域中强制跨域请求(像JSONP一样),那么将crossDomain为true,这允许你将服务器端重定向到另一个域。

scriptCharset

只有当请求时dataType为"jsonp"或"script",并且type是"GET"才会用于修改charset。

因为此时是动态创建<script>来完成脚本加载,但是如果js中的编码与页面的编码不一致时,js可能加载失败或者显示乱码或者IE下报某符号错误。设置此参数就相当于为<script>标签设置charset属性。

hearders

(默认:{})  设置HTTP请求头数据"{键:值}"。此设置发生在:jQuery所有影响HTTP头的参数(options)设置之后,beforeSend回调函数之前

statusCode

(默认:{})  定义一组HTTP状态码与回调函数的映射,当响应的状态码有匹配statusCode则会触发对应回调函数。例如,如果响应状态是404,将触发以下警报:

1
2
3
4
5
$.ajax({
    statusCode: {404: function() {
       alert(\'page not found\');
    }
});

traditional

如果你想要用传统的方式来序列化数据,那么就设置为true。请参考$.param()深度递归详解

xhrFields

声明附加到XMLHttpRequest对象的自定义“key-value”数组。例如,如果需要的话,你可以用它来设置跨域的withCredentials为true,即:

xhrFields: { withCredentials: true }  

5个局部事件

beforeSend、dataFilter、success、error、complete。(详见后面事件介绍部分)

 

由ajax函数内部解析或内部提供

dataTypes

由dataType按空格拆分所得。

isLocal

根据协议确定当前url请求的是否为本地请求。

jQuery中定义默认值为:

1
isLocal:/^(?:about|app|app\\-storage|.+\\-extension|file|res|widget):$/.test(/^([\\w\\+\\.\\-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+))?)?/.exec(url))

hasContent

非GET或HEAD请求为true,用于处理data和contentType参数。

contents

一个"{类型字符串:正则表达式}"的对象,倘若dataTypes[0]为“*”时,用contents中的正则表达式去匹配contentType,匹配成功则用“类型字符串”覆盖dataTypes[0]。

jQuery内部定义如下:

1
2
3
4
5
6
contents: {
    xml: /xml/,
    html: /html/,
    json: /json/,
    script: /javascript|ecmascript/
}

accepts

以上是关于触碰jQuery:AJAX异步详解(转)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jQuery ajax() 方法异步提交 验证用户登录

异步编程Ajax的详解,并对其进行封装整理

JQuery快速入门-Ajax

Ajax详解

Ajax详解

ajax详解

(c)2006-2024 SYSTEM All Rights Reserved IT常识