Ajax与HTTP协议
AJAX
实现Ajax的标准方法是直接使用XMLHttpRequest(XHR)对象,也可以使用Ajax的封装库如Prototype或jQuery。
手动的创建XHR对象:
if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else if (window.ActiveXObject) {// 一般IE xhr = new ActiveXObject(“Microsoft.XMLHTTP”); }
调用XHR对象的open方法,“GET”方式请求URL:’
xhr.open( “GET”, “my-dynamic-content.jsp?id=” +encodeURI(myId), true );
回调方法来处理响应:
xhr.onreadystatechange = function(){ processReqChange(req); }
发送请求:
xhr.send(null);
XHR对象的全部细节(方法)如下:
方法open(method, url, async),打开一个URL连接,method为HTTP请求方式(POST/GET...),url为HTTP请求的URL路径,async为是否创建一个异步请求(true/false)。
方法onreadystatechange,声明一个方法对象(function Object)作为回调方法,类似于浏览器事件模型中的onclick、onload方法。
方法setRequestHeader(namevalue),设置HTTP请求的请求头。
方法send(body),发送请求体,可以是字符串。
方法abort(),停止XHR对象监听HTTP响应。
方法readyState,响应(response)生命周期的阶段状态,只有send方法被调用之后状态值被填充或者类似于被set给readyState。
方法httpStatus,HTTP返回code,整数,只有响应达到被加载(返回到页面)状态时才会被填充code值如404等。
方法responseText,响应体(Javascript字符串),只有响应达到interactive状态时才会设置响应体。
方法responseXML,响应体(XML文档对象),只有响应达到interactive状态时才会设置响应体。
方法getResponseHeader(name),通过名字读取响应头。
方法getAllResponseHeaders(),获取所有响应头名字的数组。
HTTP协议
HTTP是一个没有状态的(不会记住或存储上一次的HTTP过程的状态)请求-响应(request-response) 协议。
请求和响应都包含请求头或响应头header和可选的请求体或响应体body(自由的文本)。
只有POST请求包含一个body。
一个请求定义一个动作或方法(POST/GET...)。
请求和响应的Mime类型可以通过header中的Content-type进行设置。
常用的HTTP请求方式(99%的时间只需要使用POST和GET)
GET:严格的说,GET只用于获取数据,而不会使web服务器(中的数据)发生变化。GET请求不包含请求体body,请求参数包含在URL的请求字符串中。
POST:用于更新web服务器上的数据,通过请求体body传递参数或数据(data);
REST风格的Web Service,通常使用HTTP verbs来映射CRUD操作:
PUT -- Create -- 对域模型(domain model)添加一个新的对象实例。
GET-- Read-- 从web服务器获取已经存在的域模型对象。
POST-- Update-- 更新已经存在的域模型对象。
DELETE-- Delete-- 从域模型中删除一个已经存在的对象。
常用的MIME类型
application/x-wwwform-urlencoded :经过编码的键值对请求字符串(body),web服务器需要解码字符串获得参数。
text/xml,application/xml:Body是XML文档。
text/plain:普通文本。
text/html, text/xhtml:Body是(X)HTML内容,web服务器端发送的标准web页面或内容片段。
text/javascript:Body是一段JavaScript代码。
image/png, image/jpeg, image/gif:Body是二进制图像。
处理HTTP响应
xhr.onreadystatechange=function(){ if (xhr.readyState==4){ if (xhr.status==200){ parseResponse(xhr); }else{ //handle the HTTP error... } }; };
XHR对象的ReadyState值:
0 -- 未初始化 -- 请求还未被发送
1 -- 加载中 -- 响应还未到达(浏览器)
2 -- 加载完成 -- 可以读取响应头了
3 -- 活动的(Interactive) -- 响应体Body不完整,但是可以被读取
4 -- 完成 -- 响应体Body是完整的
处理HTTP响应---parseResponse(xhr)
如果响应为HTML代码如:
<table class=’item selected’> <tr> <td rowspan=’3’ valign=’top’><div class=’itemIcon’><img src=’../images/kmoon.png’></div></td> <td class=’itemTitle’>The Moon on a Stick</td> </tr> <tr> <td valign=’top’>What every project manager wants - and they want it yesterday!<br/><br/><i>NB: Stick not included.</i></td> </tr> <tr> <td><div class=’price’>$365.00</div></td> </tr> </tr> </table>
处理函数如(往id为myDiv的div中插入上述返回的HTML):
function parseResponse(xhr){ var div=document.getElementById(“myDiv”); div.innerHTML=xhr.responseText; }
如果响应为JSON格式的数据如:
{ imgSrc: “kmoon.png”, title: “The Moon on a Stick”, description: “What every project manager wants - and they want it yesterday!<br/><br/><i>NB: Stick not included.</i>”, price: “365.00” }
处理函数如:
function parseResponse(xhr){ var jsonObj=eval(“(“+xhr.responseText+”)”); setImgSrc(jsonObj.imgSrc); setTitle(jsonObj.title); }
如果响应为XML文档或片段如:
<item imgSrc=”kmoon.png” price=”365.00”> <title>The Moon on a Stick</title> <description><![CDATA[What every project manager wants - and they want it yesterday!<br/><br/><i>NB: Stick not included.</i>]]></description> </item>
处理函数(还有其它方式解析XML,略)如:
function parseResponse(xhr){ var xmlDoc=xhr.responseXML; var item=xmlDoc.getElementsByTagName(‘item’)[0]; var imgSrc=item.getAttribute(‘imgSrc’); var title=item.getElementsByTagName(‘title’)[0].firstChild.data; setImgSrc(imgSrc); setTitle(title); }
一些流行的Ajax工具(js库)
Prototype Scriptaculous dojo Yahoo User Interface (YUI) Ext sarissa Mochikit jQuery MooTools Ruby on Rails(Server端)GWT
Prototype创建Ajax请求:
new Ajax.Request( “my-dynamic-content.jsp”, {
method: “post”,
params: { id: myId }, onComplete: function(response){ parseResponse(response); } } );
jQuery创建Ajax请求:
$.post( “my-dynamic-content.jsp”, { id: myId }, function(xhr){ parseResponse(xhr); } );