最近写js写的比较多,突然想到去年工作时遇到的一个很棘手的问题(当时一个页面明明已经导入jq文件,可无论如何就是不能使用jq 的代码,有时候觉得编程真的是一门玄学),由于页面里有需要异步查询的操作,就只能使用原生js去构造ajax请求了。
一. 什么是Ajax
Ajax即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。
通过与后台服务器进行少量的数据交换,Ajax可以在无需重新加载整个网页的情况下,实现网页的局部(数据)刷新。
二. XMLHttpRequest对象
XMLHttpRequest对象是ajax的核心,XMLHttpRequest 用于与后台服务器交换数据。
2.1 XMLHttpRequest对象的属性
属性 | 说明 |
---|---|
readyState | 表示XMLHttpRequest对象的状态:0:未初始化。对象已创建,未调用open; 1:open方法成功调用,但Sendf方法未调用; 2:send方法已经调用,尚未开始接受数据; 3:正在接受数据。Http响应头信息已经接受,但尚未接收完成; 4:完成,即响应数据接受完成。 |
onreadystatechange | 请求状态改变的事件触发器(readyState变化时会调用这个属性上注册的javascript函数) |
responseText | 服务器响应的文本内容 |
responseXML | 服务器响应的XML内容对应的DOM对象 |
Status | 服务器返回的http状态码。200表示“成功”,404表示“未找到”,500表示“服务器内部错误”等 |
statusText | 服务器返回状态的文本信息 |
2.2 XMLHttpRequest对象的方法
方法 | 说明 |
---|---|
open(method,surl,asynch) | 指定和服务器端交互的HTTP方法,URL地址等其他请求信息; method:表示http请求方法,一般使用"GET","POST". url:表示请求的服务器的地址; asynch:表示是否采用异步方法,true为异步,false为同步; |
send(content) | 向服务器发出请求,如果采用异步方式,该方法会立即返回。 content可以指定为null表示不发送数据,其内容可以是DOM对象,输入流或字符串。 |
setRequestHeader(header,value) | 设置HTTP请求中的指定头部header的值为value. 此方法需在open方法以后调用,一般在post方式中使用。 |
getAllResponseHeaders() | 返回包含Http的所有响应头信息,其中相应头包括Content-length,date,uri等内容。 返回值是一个字符串,包含所有头信息,其中每个键名和键值用冒号分开,每一组键之间用CR和LF(回车加换行符)来分隔! |
getResponseHeader(header) | 返回HTTP响应头中指定的键名header对应的值 |
abort() | 停止当前http请求。对应的XMLHttpRequest对象会复位到未初始化的状态。
|
三. ajax请求流程
1.创建XMLHttpRequest对象
2.注册回调函数
3.初始化XMLHttpRequest对象,设置连接信息
4.发送数据,开始和服务器端交互
5.定义回调函数,该回调函数负责接收从服务器端返回过来的数据
四. 代码实现
我这里做了几个封装
1.创建XMLHttpRequest对象
//惰性载入创建 xhr 对象 function createXHR() { if ('XMLHttpRequest' in window) { createXHR = function() { return new XMLHttpRequest(); }; } else if ('ActiveXObject' in window) { createXHR = function() { return new ActiveXObject("Msxml2.XMLHTTP"); }; } else { createXHR = function() { throw new Error("Ajax is not supported by this browser"); }; } return createXHR(); }
2.执行Ajax请求
// Ajax 执行 function request(ajaxData) { var xhr = createXHR(); ajaxData.before && ajaxData.before(); // 通过事件来处理异步请求 xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { if (ajaxData.dataType == 'json') { // 获取服务器返回的 json 对象 jsonStr = xhr.responseText; json1 = eval('(' + jsonStr + ')'), json2 = (new Function('return ' + jsonStr))(); ajaxData.callback(json2); // ajaxData.callback(JSON.parse(xhr.responseText)); // 原生方法,IE6/7 不支持 } else ajaxData.callback(xhr.responseText); } else { ajaxData.error && ajaxData.error(xhr.responseText); } } }; // 设置请求参数 xhr.open(ajaxData.type, ajaxData.url); if (ajaxData.noCache == true) xhr.setRequestHeader('If-Modified-Since', '0'); if (ajaxData.data) { xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send(ajaxData.data); } else { xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.send(null); } return xhr; }
3.封装post方法和get方法
//ajax的post请求 function post(ajaxData) { ajaxData.type = 'POST'; var _result = request(ajaxData); return _result; } //ajax的get请求 function get(ajaxData) { ajaxData.type = 'GET'; ajaxData.data = null; var _result = request(ajaxData); return _result; }
4.调用示例
/** * url:请求地址 * data:请求数据,如username=小明&password=123456 * calllback: 自定义回调函数 */ post({ url:url, data:data, callback:function(xhr){ //回调函数代码 //xhr表示服务器回传的数据 } } });
五.总结
使用原生js去构造ajax请求确实稍显繁琐,但是理解掌握这个,会对ajax请求原理和流程有很好的理解。主要就是需要理解XMLHttpRequest对象的作用。