使用 XMLHttpRequest(一):发送请求获取响应
XMLHttpRequest
浏览器在 XMLHttpRequest
类上定义了它们的 HTTP API,这个类的每个实例都表示一个独立的请求/响应对,并且这个对象的属性和方法允许指定请求细节和提取响应数据。
注:Microsoft 最早把
XMLHttpRequest
对象引入到 IE5 中,且在 IE5 和 IE6 中它只是一个 ActiveX 对象。
一个 HTTP 请求由四部分组成:
- HTTP 请求方法或动作(verb)
- 正在请求的URL
- 可选的请求头信息(包含身份认证信息)
- 可选的请求主体
一个 HTTP 响应包含三个部分:
- 状态码
- 响应头
- 响应主体
关于 HTTP 请求和响应的底层细节,可以参考网络协议系列中对应的 HTTP 协议教程:HTTP 协议概述。
指定请求
创建 XMLHttpRequest
对象之后,发起 HTTP 请求的下一步是调用 XMLHttpRequest
对象的 open()
方法去指定这个请求的两个必需部分:方法和URL。如果请求头的话,可以通过 setRequestHeader
方法进行设置。发起 HTTP 请求的最后一步是指定可选的请求主体并通过 send()
方法发送。
下面是一个通过 POST 方法发送文本字符串到服务器的示例:
function postMessage(msg) {
var request = new XMLHttpRequest();
request.open('POST', "/log.php");
request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
request.send(msg);
}
取得响应
我们可以通过 XMLHttpRequest
对象的 status
和 statusText
属性获取 HTTP 状态码,通过 getResponseHeader()
和 getAllResponseHeaders()
查询响应头,响应主体可以通过responseText
属性获取文本形式,通过 responseXML
获取 Document 形式。
通过 XMLHttpRequest
发送 HTTP 请求是异步非阻塞的,为了在响应准备就绪时得到通知,必须监听 XMLHttpRequest
的 readystatechange
事件,理解这个事件必须先了解 readyState
属性。
readyState
是一个整数,表示 HTTP 请求的状态:
理论上,每次 readyState
属性改变都会触发 readystatechange
事件,所以我们要监听响应完成状态,只需要在事件处理程序里一直检测 readyState
属性值即可:
function getText(url, callback) {
var request = new XMLHttpRequest();
request.open("GET", url);
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
var type = request.getResponseHeader("Content-Type");
if (type.match(/^text/))
callback(request.responseText);
}
};
request.send(null);
}
同步响应
XMLHttpRequest
也支持同步响应,如果把 false
作为第三个参数传递给 open()
方法,那么 send()
将阻塞直到请求完成,这种情况下,不需要事件处理程序:
function getText(url, callback) {
var request = new XMLHttpRequest();
request.open("GET", url, false);
request.send(null);
if (request.status !== 200)
throw new Error(request.statusText);
var type = request.getResponseHeader("Content-Type");
if (!type.match(/^text/))
throw new Error("Expected textual response; got: " + type);
callback(request.responseText);
}
响应解码
如果服务器想发送诸如对象或数组这样的结构化数据作为响应,它应该传输 JSON 编码的字符串数据。当接收 JSON 格式数据时,可以将 responseText
传递给 JSON.parse()
进行解析。
服务器响应的正常解码是假设服务器为这个响应发送了「Content-Type」和正确的 MIME 类型,否则将出现与预期不符的结果。当然你也可以在客户端覆盖响应中的 MIME 类型:
request.overrideMimeType("text/plain; charset=UTF-8");
No Comments