好用的建筑设计网站,网站的用户体验主要有那些类型,中国最近热点新闻事件,企业管理咨询师考试传送门#xff1a;异步编程系列目录…… 示例源码#xff1a;触碰jQuery#xff1a;AJAX异步详解.rar AJAX 全称 Asynchronous JavaScript and XML#xff08;异步的 JavaScript 和 XML#xff09;。它并非一种新的技术#xff0c;而是以下几种原有技术的结合体。 1) 使… 传送门异步编程系列目录…… 示例源码触碰jQueryAJAX异步详解.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手段如使用隐藏的或内嵌的框架(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同步。 注释当您使用asyncfalse 时,JavaScript 会等到服务器响应就绪才继续执行。如果服务器繁忙或缓慢应用程序会挂起或停止。此时不需要编写onreadystatechange回调函数把代码放到 send() 语句后面即可。 4) bstrUser[可选]如果服务器需要验证此处指定用户名如果未指定当服务器需要验证时会弹出验证窗口。 5) bstrPassword[可选]验证信息中的密码部分如果用户名为空则此值将被忽略。 getRequestHeader(name) 获取指定的相应头部信息 setRequestHeader(name,value) 自定义HTTP头部信息。需在open()方法之后和send()之前调用才能成功发送请求头部信息。 传送门HTTP 头部详解 Accept 浏览器能够处理的媒体类型 Accept-Charset 浏览器申明自己接收的字符集 Accept-Encoding 浏览器申明自己接收的编码方法通常指定压缩方法是否支持压缩支持什么压缩方法gzipdeflate Host 客户端指定要请求的WEB服务器的域名/IP 地址和端口号 Referer 发出请求的页面的URI Content-Type 标明发送或者接收的实体的MIME类型。传送门 1、HTTP 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 成功 表示成功处理了请求的状态代码。Eg200 3xx 重定向 表示要完成请求需要进一步操作。通常这些状态代码用来重定向。Eg304 4xx请求错误 这些状态代码表示请求可能出错导致服务器无法正常处理。Eg404 5xx服务器错误 这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误而不是请求出错。Eg500 statusText字符表示 返回当前请求的状态文本egOK status200 responseText 将响应信息作为字符串返回 responseXML 将响应信息格式化为Xml Document对象并返回 responseBody只有微软的IE支持 将响应信息正文以unsigned byte数组形式返回(二进制数据) responseStream只有IE的某些版本支持 以Ado Stream对象(二进制流)的形式返回响应信息 getResponseHeader(name) 从响应信息中获取指定的http头 getAllResponseHeaders() 获取响应的所有http头 overrideMimeType 通常用于重写服务器响应的MIME类型。Eg正常情况下XMLHttpRequest只接收文本数据但我们可以重写MIME为“text/plain; charsetx-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, funcGetServerTime , 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?funcGetBinaryData, { type: get, dataType: text, cache: false, mimeType: text/plain; charsetx-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; charsetx-user-defined参数。 b) 没有对服务器的MIME类型进行重写导致返回信息被浏览器格式化后输出的二进制数据与服务器不同。并且不同浏览器格式化后输出的二进制数据都有差异。 2) 接收二进制数据方法BresponseType属性 在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; ibyteArray.byteLength; 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 来获得一致的结果。 可用值: 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 多用途互联网邮件扩展MIMEMultipurpose Internet Mail Extensions用于重写服务器端响应的MIME类型。 data 发送到服务器的数据。可以是一个查询字符串比如 key1value1amp;key2value2 也可以是一个映射比如 {key1: value1, key2: value2} 。如果使用了后者的形式则数据在发送前会通过jQuery.param()函数转换成查询字符串。这个处理过程也可以通过设置processData选项为false来回避。 processData (默认: true) 默认情况下发送到服务器的数据即data参数将被转换为字符串以配合默认内容类型 application/x-www-form-urlencoded。如果要发送 DOM 树信息或其它不希望转换的信息请设置为 false。 jQuery中的处理方式 1 2 3 if ( s.datas.processDatatypeofs.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?funcGetBinaryData_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 浏览器能够处理的媒体类型其值取决于dataTypes[0]参数。 jQuery内部定义如下 1 2 3 4 5 6 7 8 accepts: { xml: application/xml, text/xml, html: text/html, text: text/plain, json: application/json, text/javascript, script: text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, *: allTypes // dataTypes[0]匹配不上时取此值 } responseFields jqXHR超集设置“数据类型:属性”对应关系在返回响应数据时用于确定创建哪个属性变量。 jQuery中定义如下 1 2 3 4 responseFields: { xml: responseXML, text: responseText } converters 存储数据类型对应的转换器根据dataTypes获取对应转换器用于对响应数据response进行处理。该处理发生在dataFilter回调函数之后。 1 2 3 4 5 6 7 8 9 10 converters: { * text: window.String, text html: true, text json: jQuery.parseJSON, text xml: jQuery.parseXML, text script: function( text ) { jQuery.globalEval( text ); // 执行脚本 return text; } } 2) jqXHR对象 为不同浏览器内置的XMLHttpRequest提供了一致的超集。对于XMLHttpRequest之外的传输机制比如JSONP请求jXHR对象也可以进行处理。 超集与真子集 如果一个集合S2中的每一个元素都在集合S1中且集合S1中可能包含S2中没有的元素则集合S1就是S2的一个超集。 S1是S2的超集则S2是S1的真子集反之亦然。 jqXHR对象我们常常使用如下成员这些成员主要用于ajax的全局事件和局部事件并且做为$.ajax()函数返回值返回。 1 2 3 4 5 6 7 8 9 10 jqXHR:{ readyState ,setRequestHeader: function( name, value ) ,getAllResponseHeaders: function() ,getResponseHeader: function( key ) ,overrideMimeType: function( type ) ,abort: function( statusText ) ,responseText ,responseXML } 另外jqXHR的全部成员如下 在图中我们看到一些陌生的函数比如done()、fail()、promise()、isResolve()、isRejected()、then()、always()、progress()等都是jQuery的deferred对象API。 开发网站的过程中我们经常遇到某些耗时很长的javascript操作。其中既有异步的操作比如ajax读取服务器数据也有同步的操作比如遍历一个大型数组它们都不是立即能得到结果的。 通常的做法是为它们指定回调函数callback。即事先规定一旦它们运行结束应该调用哪些函数。但是在回调函数方面jQuery的功能非常弱。为了改变这一点jQuery开发团队就设计了deferred对象。 简单说deferred对象就是jQuery的回调函数解决方案。在英语中defer的意思是延迟所以deferred对象的含义就是延迟到未来某个点再执行。 它解决了如何处理耗时操作的问题对那些操作提供了更好的控制以及统一的编程接口。 更专业的资源jQuery的deferred对象详解 2. jQuery Ajax事件 jQuery框架中伴随Ajax请求会触发若干事件我们可以订阅这些事件并在其中处理我们的逻辑。在jQuery中有两种Ajax事件局部事件和全局事件。 1) 局部事件回调函数在$.ajax()方法的options参数中声明可以用来设置请求数据和获取、处理响应数据。 beforeSend 该函数可在发送请求前修改XMLHttpRequest对象如添加自定义 HTTP 头。 签名function (jqXHR,s) { } 函数说明传入jqXHR、s对象 dataFilter 在请求成功之后调用。若状态码为304(未修改)则不触发此回调。 签名function (data, dataType) { return newData; } 函数说明传入返回的数据、dataType参数的值。并且必须返回新的数据传递给success回调函数 success 请求成功时触发。 签名function (data,statusText,jqXHR) { } 函数说明传入返回的数据、描述状态的字符串”success”、jqXHR对象 error 请求失败时调用此函数。 签名function (jqXHR, textStatus, errorThrown) { } 函数说明传入jqXHR对象、描述状态的字符串”error”、错误信息 complete 请求完成后回调函数 (请求成功或失败之后均调用) 签名function (jqXHR, textStatus) { } 函数说明传入jqXHR对象、描述状态的字符串可能值No Transport、timeout、notmodified---304 、parsererror、success、error 定义方式例如 1 2 3 4 5 6 7 8 9 10 $.ajax({ // ... beforeSend: function(){ // Handle the beforeSend event }, complete: function(){ // Handle the complete event } // ... }); 2) 全局事件每次Ajax请求都会触发它会向DOM中的所有元素广播你只需为DOM中任意元素bind好全局事件即会触发若绑定多次则会依次触发为事件注册的回调函数。 ajaxStart 开始新的Ajax请求并且此时jQuery对象上没有其他ajax请求正在进行。 签名function(e) 函数说明传入事件对象 ajaxSend 当一个Ajax请求开始时触发 签名function(e,jqXHR,s) 函数说明传入事件对象、jqXHR、s对象 ajaxSuccess 全局的请求成功 签名function(e,jqXHR,s,data) 函数说明传入事件对象、jqXHR、s对象、请求成功返回的相应数据 ajaxError 全局的发生错误时触发 签名function(e,jqXHR,s,errorData) 函数说明传入事件对象、jqXHR、s对象、请求失败返回的错误信息 ajaxComplete 全局的请求完成时触发 签名function(e,jqXHR,s) 函数说明传入事件对象、jqXHR、s对象 ajaxStop 当jQuery对象上正在进行Ajax请求都结束时触发。 签名function(e) 函数说明传入事件对象 全局事件在jQuery中的声明方式 1 2 3 4 5 jQuery.each( ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend.split( ), function( i, o ){ jQuery.fn[ o ] function( f ){ return this.on( o, f ); }; }); 所以我们可以使用下面两种方式定义全局事件 1 2 3 4 // 可以用bind来绑定用unbind来取消绑定。 $(#loading).bind(ajaxSend, function(){ … }); 或者 $(#loading).ajaxStart(function(){ … }); 3) ajax方法完整的事件流 4) 示例$.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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 // 全局事件 $(#div_event).ajaxStart(function (e) { doAddEvent4textarea(txt_event, 触发ajaxStart回调函数); }); $(#div_event).ajaxSend(function (e) { doAddEvent4textarea(txt_event, 触发ajaxSend回调函数); }); $(#div_event).ajaxSuccess(function (e, jqXHR, s, data) { doAddEvent4textarea(txt_event, 触发ajaxSuccess回调函数); }); $(#div_event).ajaxError(function (e, jqXHR, s, errorData) { doAddEvent4textarea(txt_event, 触发ajaxError回调函数); }); $(#div_event).ajaxComplete(function (e, jqXHR, s) { doAddEvent4textarea(txt_event, 触发ajaxComplete回调函数); }); $(#div_event).ajaxStop(function (e) { doAddEvent4textarea(txt_event, 触发ajaxStop回调函数); }); // 局部事件 function bindLocalEvent(e) { var textareaid e.data.textareaid; var global e.data.global; $.ajax(AjaxHandler.ashx?funcbtn_nowTime_long, { type: get, dataType: text, global: global, cache: false, beforeSend: function (jqXHR, s) { doAddEvent4textarea(textareaid, 触发beforeSend回调函数); }, dataFilter: function (data, dataType) { doAddEvent4textarea(textareaid, 触发dataFilter回调函数); }, success: function (data, statusText, jqXHR) { doAddEvent4textarea(textareaid, 触发success回调函数); }, error: function (jqXHR, textStatus, errorThrown) { doAddEvent4textarea(textareaid, 触发error回调函数); }, complete: function (jqXHR, textStatus) { doAddEvent4textarea(textareaid, 触发complete回调函数); } }); } function doAddEvent4textarea(textareaid, txt) { var textarea $(# textareaid); textarea.val(textarea.val() \r\n txt); } 效果图 5) $.ajax()方法的全局事件典型用例 你的页面存在多个甚至为数不少的ajax请求但是这些ajax请求都有相同的消息机制。ajax请求开始前显示一个提示框提示“正在读取数据”ajax请求成功时提示框显示“数据获取成功”ajax请求结束后隐藏提示框。 a) 不使用全局事件的做法是 给$.ajax()加上beforeSend、success、complete回调函数在回调函数中加上处理提示框。 b) 使用全局事件的做法是 1 2 3 4 5 6 $(document).ajaxStart(onStart) .ajaxComplete(onComplete) .ajaxSuccess(onSuccess); function onStart(event) { //..... } function onComplete(event, xhr, settings) { //..... } function onSuccess(event, xhr, settings) { //..... } 3. jQuery ajax相关函数 1) jQuery.ajaxSetup({ }) jQuery.ajax()函数中的所有的参数选项都可以通过jQuery.ajaxSetup()函数来全局设置默认值。 2) $.ajax()函数的封装 a) $().load(url [, params] [, callback]) 请求远程的HTML文件代码(dataType: html)默认使用 GET 方式如果传递了params参数则使用Post方式。在请求“成功”完成时将responseText属性值插入至DOM中。但不管请求是否成功完成“在最后”都会执行callback回调函数(即complete:callback)。 b) jQuery.get(url [, data] [, callback] [, type] ) 通过HTTP GET请求载入数据并在请求成功时执行回调函数即success: callback。 c) jQuery.getJSON(url [, data] [, callback] ) 通过 HTTP GET 请求载入 JSON 数据。相当于: jQuery.get(url, [data],[callback], json) 可以通过使用JSONP 形式的回调函数来加载其他网域的JSON数据。 d) jQuery.getScript(url [, callback] ) 通过 HTTP GET 请求载入并执行一个 JavaScript 文件。相当于: jQuery.get(url, null, [callback], script) 可以跨域调用 JavaScript 文件。 e) jQuery.post(url [, data] [, callback] [, type] ) 通过 HTTP POST 请求载入信息并在请求成功时执行回调函数即success: callback。 3) 对象序列化 a) jQuery.param(object,traditional) 创建数组或对象的序列化表示该序列化可在ajax请求时在URL查询字符串中使用。 序列化过程中会使用encodeURIComponent()函数把字符串作为URI组件进行编码。 encodeURIComponent() 方法不会对 ASCII 字母和数字进行编码也不会对这些 ASCII 标点符号进行编码 - _ . ! ~ * ( ) 。其他字符比如;/?:$,# 这些用于分隔 URI 组件的标点符号都是由一个或多个十六进制的转义序列替换的。 1 2 3 4 5 6 // 在param中会进行如下处理 function( key, value ) { // 如果value是函数则取其函数返回值 value jQuery.isFunction( value ) ? value() : value; s[ s.length ] encodeURIComponent( key ) encodeURIComponent( value ); }; 对于 jQuery 1.4$.param() 方法将会通过深度递归的方式序列化对象以便符合现代化脚本语言的需求比如 PHP、Ruby on Rails 等。你可以传递traditional true 或在ajax功能中传递包含traditional的options参数。 传送门$.param()深度递归详解和$.param() 示例 b) $().serializeArray() 可以将一个或多个表单元素比如 input、 textarea等或者 form 元素本身的jQuery对象序列化为JSON对象。非 JSON 字符串。需要使用插件或者第三方库进行字符串化操作 特别说明元素不能被禁用禁用的元素不会被包括在内并且元素应当有含有 name 属性。提交按钮的值也不会被序列化。文件选择元素的数据也不会被序列化。 传送门$().serializeArray() 示例 c) $().serialize() 可以将一个或多个表单元素比如 input、 textarea等或者 form 元素本身的jQuery对象序列化为经过URL编码转换后的字符串可直接用在URL查询字符串中。 jQuery内部定义 1 2 3 serialize: function() { return jQuery.param( this.serializeArray() ); } 传送门$().serialize()示例 $.ajax()中常见应用示例 1. cache和ifModified参数 1) cache参数GET和POST最重要的区别传送门 语义上GET是获取指定URL上的资源是读操作重要的一点是不论对某个资源GET多少次它的状态是不会改变的在这个意义上我们说GET是安全的不是被密码学或者数据保护意义上的安全。因为GET是安全的所以GET返回的内容可以被浏览器Cache服务器缓存起来。 而POST的语意是对指定资源“追加/添加”数据所以是不安全的每次提交的POST参与的代码都会认为这个操作会修改操作对象资源的状态于是浏览器在你按下F5的时候会跳出确认框缓存服务器不会缓存POST请求返回内容。 2) ifModified参数通过ifModified参数提高请求性能即“条件GET”Last-Modified / If-Modified-Since和ETag / If-None-Match 当你请求的资源并不是一层不变的时候即不能简单的一直使用客户端缓存时你可能通过将cache设置为false来发送请求这实际上是在url加上时间戳组合成新的url每次发送新的请求这明显加大了服务器的压力。 对于这种情况我们可以通过ifModified参数改进缓存方式即cache和ifModified都设置为true仅在请求的数据改变时重新获取。通过这种方式请求的url不会改变并且每次都会发送到服务器只是会有检验方法验证是否需要重新获取数据从而节省带宽和开销。 更多ETag描述优点解决了Last-Modified无法解决的一些问题什么场合不应该被使用 过程如下 a) 将$.ajax()函数的cache和ifModified参数同时设置为true。 b) 客户端请求服务端A在服务端加上Last-Modified/ETag响应体一起返回。 c) 客户端缓存接收到的Last-Modified/ETag响应体并在下一次发生请求A时将缓存的Last-Modified/ETag值做为If-Modified-Since/IF-None-Match请求头一起发给服务器。 d) 服务器接收If-Modified-Since/IF-None-Match后就根据参数值检验自上次客服端请求之后资源是否有改动 i. 若还未改动则直接返回响应304和一个空的响应体。 ii. 若已改动则重新处理数据返回最新的请求数据。 e) 这样既保证不向客户端重复发出资源也保证当服务器有变化时客户端能够得到最新的资源。 这一过程中我们只需要做服务器返回Last-Modified/ETag响应头和在服务端检验数据是否失效并采取对应处理方式。其余步骤由jQuery框架的ajax()函数完成。 关键代码如下 客服端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $(#btn_nowTime_long3).bind(click, null , function () { $.ajax(AjaxHandler.ashx?funcGetServerTime4Modified, { type: get, dataType: text, cache: true, ifModified: true, success: function (data) { if (data) alert(data); }, }); }); 服务端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 if(!String.IsNullOrEmpty(context.Request.Headers[If-Modified-Since])) { if (CheckResourceValidate()) // 检查资源有效性 { // 如果资源有效则直接返回304状态码客户端回去到此状态码后会从缓存中取值。 context.Response.StatusCode 304; return; } } // 请求数据 GetServerTimeAfter2Second(); context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(5)); // 设置Last-Modified响应体 context.Response.Cache.SetLastModified(DateTime.Now); 2. 跨域请求 在JavaScript中有一个很重要的安全性限制被称为“Same-Origin Policy”同源策略。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制即JavaScript只能访问与包含它的文档在同一域下的内容。所谓同源是指域名(host)协议(protocol)端口(port)相同。 URL 说明 是否允许通信 能否通过javascript解决 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.js http://www.a.com/script/b.js 同一域名下不同文件夹 允许 http://www.a.com:8000/a.js http://www.a.com/b.js 同一域名不同端口 不允许 能 http://www.a.com/a.js https://www.a.com/b.js 同一域名不同协议http和https 不允许 不能 http://www.a.com/a.js http://70.32.92.74/b.js 域名和域名对应ip 不允许 能 http://www.cnblogs.com/a.js http://www.a.com/b.js http://script.a.com/b.js http://a.com/b.js 不同域名(host) 不允许 能 注一级域名与二级域名之间不同二级域名之间 都属于不同域名 1) $.ajax()为我们提供了两种解决方案不过都是只支持get方式分别是jQuery的jQuery.ajax“jsonp”格式和jquery.getScript()即jQuery.ajax “script”格式方式。 2) $.ajax()跨域原理分析 由于javascript的安全限制“同源策略”所以我们无法使用XMLHttpRequest直接请求别的域名下的资源。不过拥有src属性和href属性的script\img\iframe和link\a标签不受同源策略影响。$.ajax()提供的两种解决方案正是应用了动态创建script的方式来实现即生成script标签src引入脚本然后执行最后移除script标签。 3) jQuery.ajax()的jsonp和script方式的异同点 a) 相同都走$.ajax() script格式的流程不会触发全局事件和局部事件只支持GET方式POST请求会自动转化为GET请求默认不启用缓存(cache:false) b) 不同jsonp方式可以通过jsonp和jsonpCallback参数指定一个特定回调函数。 4) 示例部署说明 因为是跨域请求所以需要在本机部署两个示例程序以模拟不同域之间的访问并且在示例代码中需要修改“crossUrl”为目的域路径。 5) jsonp示例代码 客服端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // jsonp方式跨域请求(dataType:jsonp) $(#btn_cross_req1).bind(click, null , function () { $.ajax(crossUrl, { type: get, dataType: jsonp, jsonp: jsonpParamName, jsonpCallback: crossCallback, crossDomain: true, }); }); function crossCallback(data) { alert(jsonp data); } 服务端 1 2 3 4 context.Response.ContentType text/plain; string jsonpCallbackName reqCollection[jsonpParamName]; context.Response.Write(String.Format({0}(来自域:{1}的相应信息) , jsonpCallbackName, context.Request.Url.Host)); 分析 a) 因jsonp和jsonpCallback参数而改变的url如下。即默认为callbackjQuery随机值更改为jsonpParamNamecrossCallback URL:http://192.168.1.100:6567/AjaxHandler.ashx?funcCrossRequestjsonpParamNamecrossCallback_1368360234428 b) 服务器端获取到jsonp回调函数名后返回一个函数表达式。 6) 在XMLHttpRequest Level 2中新增了跨域访问方式、接收二进制等新功能详细请看XMLHttpRequest2 新技巧 最后再来一张示例截图吧 示例源码触碰jQueryAJAX异步详解.rar 本篇博文到此结束主要介绍内容是使用XMLHttpRequest实现ajax请求和XMLHttpRequest Level 2为我们所带来的改进最后重点讲解了jQuery中通过$.ajax()方法实现ajax以及各个参数的详细介绍并立举了经典示例说明了跨域请求、ajax全局事件、ajax局部事件、xhr二进制数据处理、如何高效使用缓存…… 做为一个后台工程师你是否想深入了解一些前台必须的技术呢是的我想了解并且会慢慢把所了解到的技术以博文的方式整理分享给大家。 谢谢大家查阅如果觉得文章不错还请多多帮推荐…… 文中出现比较多的相关资源链接这里整理下方便大家日后快速找到链接 1) jQuery相关 jQueryAPI文档 jQuery百度百科(Eg模块历史版本) Ajax 技术资源中心IBM 这是有关 Ajax 编程模型信息的一站式中心包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。 jQuery.ajax()中的预过滤器和分发机制函数inspectPrefiltersOrTransports详解 jQuery的deferred对象详解 $.param()深度递归详解 2) XMLHttpRequest Level 2 的新功能相关 XMLHttpRequest 增强功能 XMLHttpRequest Level 2 使用指南 XMLHttpRequest2 新技巧 3) 跨域请求相关 JavaScript跨域总结与解决办法 总结了5种js跨域方式利用iframe标签和document.domain属性、动态创建scrip、利用iframe标签和location.hash属性、window.name实现的跨域数据传输、使用HTML5 postMessage、利用flash跨域。 域名和IP地址及域名解析 xhr注入_百度百科 说说JSON和JSONP 4) HTTP相关 HTTP深入浅出 http请求 1) 介绍了一次HTTP通信的7个步骤建立TCP连接、Web浏览器向Web服务器发送请求命令、Web浏览器发送请求头信息、Web服务器应答、Web服务器发送应答头信息、Web服务器向浏览器发送数据、Web服务器关闭TCP连接 2) 介绍HTTP请求格式 HTTP GET和POST的区别 HTTP 头部详解 HTTP Content-type对照表 格式Content-Type: [type]/[subtype]; parameter HTTP状态码一览表HTTP Status Code 5Jquery其他部分 不定义JQuery插件不要说会JQuery 作者滴答的雨 出处http://www.cnblogs.com/heyuquan/ 本文版权归作者和博客园共有欢迎转载但未经作者同意必须保留此段声明且在文章页面明显位置给出原文连接否则保留追究法律责任的权利。