Ajax技术详解
Ajax技术:Ajax描述了一种主要使用脚本(JS)操纵HTTP的web应用架构,它的主要特点是使用脚本操纵HTTP和web服务器进行数据交换,不会导致页面重载。Ajax的核心是JS的XMLHttpRequest构造函数,它定义了用脚本操纵HTTP的API。
XMLHttpRequest构造函数:每new一个XMLHttpRequest构造函数返回的对象都表示一个独立的请求/响应对,并且这个对象的属性和方法允许指定请求细节和提取响应数据。需要注意的是当你重用已存在的XMLHttpRequest,这将会终止之前通过该对象挂起的任何请求。
案例:创建一个HTTP API
//该构造函数返回的对象API能够操作HTTP请
var xhr = new XMLHttpRequest();
HTTP API的open()方法:创建了HTTP API后的下一步就是调用open()方法。这个方法有三个参数,参数一指定HTTP请求的方法,GET、POST、DELETE、HEAD、OPTIONS和PUT都能用。参数二指定了请求的URL,但URL不能是跨域的URL。参数三指定了这个请求是否异步进行,true表示异步,false表示同步。
案例:open()方法的调用
var xhr = new XMLHttpRequest();
var URL = "lookup.php?name=csh&sex=男&ie=utf-8";
xhr.open('GET', URL, true);
onreadystatechange事件:调用了open()方法后的下一步就是监听onreadystatechange事件,这个事件主要用于监听请求返回时的状态码(status属性)和返回数据的情况(readyState属性)。当status和readyState属性符合需求的时候调用回调函数。
readyState属性:readyState属性的值是一个整数,它指定了HTTP请求的状态。
0表示open()尚未调用
1表示open()已调用
2表示接收到头信息
3表示接收到响应主体
4表示响应完成
理论上,每次readyState属性改变都会触发readystatechange事件,但实际中当readyState改变为0或1时可能没有触发这个事件。当readyState值改变为4或服务器的响应完成时,所有的浏览器都触发readystatechange事件。
status属性:readyState属性的值是一个整数,它指定了HTTP的状态码。
常见的HTTP状态码:
HTTP: Status 200 – 服务器成功返回网页
HTTP: Status 404 – 请求的网页不存在
HTTP: Status 503 – 服务不可用
案例:监听onreadystatechange事件
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (){
//2xx状态与表示从缓存中直接取出的304可以看是成功的,IE(非原生的XHR对象)中会将204设置为1223,opera会在取得204时设置为0
if (xhr.readyState == 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0)){
options.callBack(converter[dataType].call(this, xhr.responseText, xhr.responseXML));
}
xhr.onreadystatechange = function (){
//2xx状态与表示从缓存中直接取出的304可以看是成功的,IE(非原生的XHR对象)中会将204设置为1223,opera会在取得204时设置为0
if (xhr.readyState == 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0)){
options.callBack(converter[dataType].call(this, xhr.responseText, xhr.responseXML));
}
};
HTTP API的send()方法:这是HTTP请求的最后一步,调用这个方法把请求发送到服务器。send()有一个可选参数,GET请求的时候为null,POST请求的时候为传给后台的数据
案例:调用send()方法
var xhr = new XMLHttpRequest();
xhr.send(null);
HTTP API的setRequestHeader()方法:该方法用于设置HTTP头信息。而在POST请求时就必须要设置HTTP头信息的Content-Type属性,用于告诉服务器发送给它的数据的MIME类型。如果调用setRequestHeader()多次,新值不会取代之前旧的值,相反,HTTP请求将包含这个头的多个副本或这个头将指定多个值。
编码请求主体:HTTP POST请求包括一个请求主体,它包含客户端传递给服务器的数据,请求主体除了是简单的文本字符串之外,还可能是复杂的数据。在Ajax应用中,一般情况下发送到服务器的很可能是一个JS对象(即把数据存放到一个对象里面,直接把这个对象发送给服务器,也就是说这个对象就是请求主体)。
案例:使用JSON编码主体来发起HTTP POST请求
function postJSON(url, data, callback){
var request = new XMLHttpRequest();
request.open('POST', url); //对指定URL发送POST请求
var request = new XMLHttpRequest();
request.open('POST', url); //对指定URL发送POST请求
request.onreadystatechange = function (){};
request.setRequestHeader("Content-Type", "application/json");
request.send(JSON.stringify(data));//data对象要转换为json类型
request.send(JSON.stringify(data));//data对象要转换为json类型
};
案例:发送一个GET请求
/**
* GET请求
* @param options 【该参数是一个object】
* {url: 'http://www.plateno.com/index.html, data: {name: 'luke'}, callBack: function(data){}}
*/
function get(options){
var xhr = new XMLHttpRequest(),
async = options.async || true;
try{
//判断是否传参数
var data = '', n = 0, a = '';
if (options.data){
data = '?';
for (var name in options.data){
n == 0 ? a = '' : a = '&';
n++;
data += a + name +'='+ encodeURI(options.data[name])
}
}
//判断是否缓存
var cache = '&' + new Data().getTime();
* GET请求
* @param options 【该参数是一个object】
* {url: 'http://www.plateno.com/index.html, data: {name: 'luke'}, callBack: function(data){}}
*/
function get(options){
var xhr = new XMLHttpRequest(),
async = options.async || true;
try{
//判断是否传参数
var data = '', n = 0, a = '';
if (options.data){
data = '?';
for (var name in options.data){
n == 0 ? a = '' : a = '&';
n++;
data += a + name +'='+ encodeURI(options.data[name])
}
}
//判断是否缓存
var cache = '&' + new Data().getTime();
if (!options.cache){cache = '';}
xhr.open('get', options.url + data + cache, async); //设置请求数据
xhr.send(); //发送请求
//监听请求过程
xhr.onreadystatechange = function (){
//2xx状态与表示从缓存中直接取出的304可以看是成功的,IE(非原生的XHR对象)中会将204设置为1223,opera会在取得204时设置为0
if (xhr.readyState == 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0)){
options.callBack.call(this, xhr.responseText, xhr.responseXML);
}
}
}catch(e){throw new Error('GET请求失败');}
}
案例:发送一个POST请求
/**
* POST请求
* @param options 【该参数是一个object】
* {url: 'http://www.plateno.com/index.html', data:{name: 'luke'}, callBack: function(data){}}
*/
function post(options) {
var xhr = new XMLHttpRequest(),
async = options.async || true;
try{
//判断是否传参数
var data = '', n = 0, a = '';
if (options.data){
for (var name in options.data){
n == 0 ? a = '' : a = '&';
n++;
data += a + name +'='+ options.data[name]
}
}
xhr.open('post', options.url, async); //设置请求数据
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8"); //设置请求头
xhr.send(data); //发送请求
//监听请求过程
xhr.onreadystatechange = function (){
//2xx状态与表示从缓存中直接取出的304可以看是成功的,IE(非原生的XHR对象)中会将204设置为1223,opera会在取得204时设置为0
if (xhr.readyState == 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0)){
options.callBack(converter[dataType].call(this, xhr.responseText, xhr.responseXML));
}
}
}catch(e){throw new Error('POST请求失败');}
* POST请求
* @param options 【该参数是一个object】
* {url: 'http://www.plateno.com/index.html', data:{name: 'luke'}, callBack: function(data){}}
*/
function post(options) {
var xhr = new XMLHttpRequest(),
async = options.async || true;
try{
//判断是否传参数
var data = '', n = 0, a = '';
if (options.data){
for (var name in options.data){
n == 0 ? a = '' : a = '&';
n++;
data += a + name +'='+ options.data[name]
}
}
xhr.open('post', options.url, async); //设置请求数据
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8"); //设置请求头
xhr.send(data); //发送请求
//监听请求过程
xhr.onreadystatechange = function (){
//2xx状态与表示从缓存中直接取出的304可以看是成功的,IE(非原生的XHR对象)中会将204设置为1223,opera会在取得204时设置为0
if (xhr.readyState == 4 && ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || xhr.status === 1223 || xhr.status === 0)){
options.callBack(converter[dataType].call(this, xhr.responseText, xhr.responseXML));
}
}
}catch(e){throw new Error('POST请求失败');}
}