XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。可以同步或异步地返回 Web 服务器的响应,并且能够以文本或者一个 DOM 文档的形式返回内容XMLHttpRequest 得到了所有现代浏览器较好的支持。唯一的浏览器依赖性涉及 XMLHttpRequest 对象的创建。在 IE 5 和 IE 6 中,必须使用特定于 IE 的 ActiveXObject() 构造函数
属性
readyState
状态 |
名称 |
描述 |
0 |
Uninitialized |
初始化状态。XMLHttpRequest 对象已创建或已被 abort() 方法重置 |
1 |
Open open() |
方法已调用,但是 send() 方法未调用。请求还没有被发送 |
2 |
Sent Send() |
方法已调用,HTTP 请求已发送到 Web 服务器。未接收到响应 |
3 |
Receiving |
所有响应头部都已经接收到。响应体开始接收但未完成 |
4 |
Loaded |
HTTP 响应已经完全接收 |
responseText
目前为止为服务器接收到的响应体(不包括头部),或者如果还没有接收到数据的话,就是空字符串。当 readyState 为 3,这个属性返回目前已经接收的响应部分。如果 readyState 为 4,这个属性保存了完整的响应体。
如果响应包含了为响应体指定字符编码的头部,就使用该编码。否则,假定使用 Unicode UTF-8
responseXML
对请求的响应,解析为 XML 并作为 Document 对象返回
status
由服务器返回的 HTTP 状态代码。当 readyState 小于 3 的时候读取这一属性会导致一个异常
statusText
这个属性用名称而不是数字指定了请求的 HTTP 的状态代码。也就是说,当状态为 200 的时候它是 “OK”,当状态为 404 的时候它是 “Not Found”。和 status 属性一样,当 readyState 小于 3 的时候读取这一属性会导致一个异常
方法
abort()
取消当前响应,关闭连接并且结束任何未决的网络活动
这个方法把 XMLHttpRequest 对象重置为 readyState 为 0 的状态,并且取消所有未决的网络活动。例如,如果请求用了太长时间,而且响应不再必要的时候,可以调用这个方法
把 HTTP 响应头部作为未解析的字符串返回。
如果 readyState 小于 3,这个方法返回 null。否则,它返回服务器发送的所有 HTTP 响应的头部。头部作为单个的字符串返回,一行一个头部。每行用换行符 “\r\n” 隔开
返回指定的 HTTP 响应头部的值。其参数是要返回的 HTTP 响应头部的名称。可以使用任何大小写来制定这个头部名字,和响应头部的比较是不区分大小写的
该方法的返回值是指定的 HTTP 响应头部的值,如果没有接收到这个头部或者 readyState 小于 3 则为空字符串。如果接收到多个有指定名称的头部,这个头部的值被连接起来并返回,使用逗号和空格分隔开各个头部的值
open()
初始化 HTTP 请求参数,例如 URL 和 HTTP 方法,但是并不发送请求
send()
发送 HTTP 请求,使用传递给 open() 方法的参数,以及传递给该方法的可选请求体
向一个打开但未发送的请求设置或添加一个 HTTP 请求
代码
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
| var xhr; function loadXMLDoc(url) { xhr = null; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else if (window.ActiveXObject) { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } if (xhr != null) { xhr.onreadystatechange = stateChange; xhr.open("GET", url, true); xhr.send(null); } else { alert("Your browser does not support XMLHTTP."); } } function stateChange() { if (xhr.readyState == 4) { // 4 = "loaded" if (xhr.status == 200) { // 200 = OK // ...our code here... } else { alert("Problem retrieving XML data"); } } }
|
封装
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| /** * EasyAjax * 简单封装 xhr 对象 * 提供 get,post 方法 * ajax.get(url, params, success, error); */ ;(function(w) { 'use strict'; var uid = 0, cache = {}; function EasyAjax(opt) { this.url = opt.url; this.method = opt.method || 'GET'; this.data = opt.data || ''; this.onsuccess = typeof opt.onsuccess === 'function' ? opt.onsuccess : null; this.onerror = typeof opt.onerror === 'function' ? opt.onerror : null; this.async = typeof opt.async !== 'undefined' ? !!opt.async : true; this.timeout = opt.timeout || 0; this.xhr = null; this._ajax(); this.uid = null; } EasyAjax.prototype = { constructor: EasyAjax, _ajax: function() { var xhr = this.xhr = this._getXHR(), that = this, data = null; if (xhr) { xhr.timeout = this.timeout; xhr.onreadystatechange = function() { that._onreadystatuschange.call(that); }; xhr.ontimeout = function() { that._ontimeout.call(that); }; if (this.method === 'POST') { xhr.open(this.method, this.url, this.async); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;'); data = json2params(this.data); } else { xhr.open(this.method, parseURL(this.url, this.data), this.async); } xhr.send(data); } }, _getXHR: function() { var xhr = null; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else if (window.ActiveXObject) { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } return xhr; }, _onreadystatuschange: function() { var xhr = this.xhr; if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { this.onsuccess && this.onsuccess(xhr.responseText, xhr.statusText); } else { this.onerror && this.onerror(xhr.responseText, xhr.statusText); } this._destory(); } }, _ontimeout: function() { console.error('ajax timeout: ' + this.timeout); // TODO }, _destory: function() { cache[this.uid] = null; }, abort: function() { return this.xhr.abort(); } }; function parseURL(url, json) { var params = json2params(json); return params.length > 0 ? (url + (url.indexOf('?') > -1 ? '&' : '?') + json2params(json)) : url; } function json2params(json) { if (typeof json === 'string') { return json; } var str = ''; for (var i in json) { if (json.hasOwnProperty(i) && json[i] != null) { str += i + '=' + json[i] + '&'; } } if (str.lastIndexOf('&') > -1) { str = str.slice(0, -1); } return str; } function init() { var obj = {}, method = ['get', 'post']; for (var i = 0; i < method.length; i++) { obj[method[i]] = factory(method[i]); } return obj; } function factory(m) { m = m.toUpperCase(); return function(url, data, onsuccess, onerror) { var ajax = null; if (typeof url === 'string') { ajax = new EasyAjax({ url: url, data: data, method: m, onsuccess: onsuccess, onerror: onerror }); } else if (typeof url === 'object') { url.method = m; ajax = new EasyAjax(url); } ajax.uid = uid++; cache[ajax.uid] = ajax; return ajax; } } w.ajax = init(); })(window);
|
1 2 3 4 5 6 7 8 9
| // 示例 ajax.get('http://uc.cn', { a:1, b:2 }, function(data, status) { render(JSON.parse(data)); }, function(data, status) { console.error(status); });
|