1. XMLHttpRequest对象
XMLHttpRequest对象用于从JavaScript发出HTTP请求,下面是典型用法.
//新建一个XMLHttpRequest实例对象
var xhr = new XMLHttpRequest();
//指定通信过程中状态改变时的回调函数
xhr.onreadystatechange = function() {
//通信成功时,状态值为4
var completed = 4;
if(xhr.readyState === completed){
if(xhr.status === 200){
//处理服务器发送过来的信息
}else{
//处理错误
}
}
};
//open方式用于指定HTTP动词,请求的网址,是否异步
xhr.open('GET', '/endpoint', true);
//发送HTTP请求
xhr.send(null);
Open()
- 发送方法:”GET”,”POST”,”PUT”,”DELETE”
- 网址
- 是否异步,true表示异步,false表示同步
xhr.open('OPEN',9 encodeRUI('someURL'));
//设置HTTP请求的头信息
xhr.setRequestHeader('content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {};
//用于实际翻出HTTP请求,如果不带参数,只包含头信息,如:GET;如果有参数,还带有具体数据信息如:POST
xhr.send(encodeURI('dataString'));
send方法课发送许多类型的数据:
void send();
void send(ArrayBuffer data);
void send(Blob data);
void send(Document data);
void send(DOMString data);
void send(FormData data);
Blob类型可以用来发送二进制数据,这使得通过Ajax上传文件成为可能。
readyState属性和readyStateChange事件
通信过程中,每当状态发生改变,readyState属性的值就会改变
这个值每改变一次,都会触发readyStateChange事件.我们可以指定这个事件的回调函数,对不同状态进行处理.
progress事件
上传文件时,XMLHttpRequest对象的upload属性有一个progress,会不断返回上传进度.
服务器返回的信息
status属性
返回HTTP状态码.
responseText属性
服务器返回的文本数据
setRequestHeader方法
用于设置HTTP头信息
xhr.setRequestHeader('Content-type', 'application/json');
xhr.setRequestHeader('Content-Length', JSON.stringify(data).length);
xhr.send(JSON.stringify(data));
overrideMimeType方法
指定服务器返回数据的MIME类型.
如果希望从服务器取回二进制数据,就要使用这个方法,认为将数据类型伪装成文本数据.
responseType属性
XMLHttpRequest对象有一个responseType属性,用来指定服务器返回数据(xhr.response)的类型.
- ‘text’:返回了性为字符串,默认值
- ‘arraybuffer’: 返回类型为ArrayBuffer
- ‘blob’: 返回类型为Blob
- ‘document’: 返回类型为Document
- ‘json’: 返回类型为JSON object
文件上传
<form id="file-form" action="handler.php" method="post">
<input type="file" id="file-select" name="photos[]" multiple />
<button type="submit" id="upload-button">上传</button>
</form>
HTML代码中,file控件的multiple属性
,可以指定一次选多个文件
file对象的files属性
,返回一个FileList对象
var fileSelect = document.getElementById('file-select');
var files = fileSelect.files;
//新建一个FormData对象实例,模拟发送到服务器的表单数据
var formData = new FormData();
for ( var i = 0;i < files.length;i++ ){
var file = file[i];
if(!file.type.match('image.*')) {
continue;
}
formData.append('photos[]', file, file.name);
}
//最后使用Ajax方法向服务器上传文件
var xhr = new XMLHttpRequest();
xhr.open('POST', 'handler.php', true);
xhr.onload = function() {
if(xhr.status !== 200) {
alert('An error occurred!');
}
}
xhr.send(formData);
//除了FormData接口上传,也可以直接使用FileAPI上传
var file = document.getElementById('test-input').files[0];
var xhr = new XMLHttpRequest();
xhr.open('POST', 'muserver.uploads');
xhr.setRequestHeader('Content-Type', file.type);
xhr.send(file);
FormData对象的append方法,除了可以添加文件,还可以添加二进制对象(Blob)或者字符串。第一个参数是表单的控件名,第二个参数是实际的值,第三个参数是可选的,通常是文件名。
JSONP
用于服务器与客户端之间的数据传输,主要为了规避浏览器的同域限制.
function addScriptTag(src){
var scipt = document.createElement('script');
script.setAttribute("type", "text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
addScriptTag("HTTP://example.com/ip?callback=foo");
}
function foo(data) {
console.log('your public IP address is: ' + data.ip);
}
许多服务器支持JSONP指定回调函数的名称,直接将JSON数据放入回调函数的参数,如此一来就省略了将字符串解析为JSON对象的步骤。
jQuery的 getJSON方法就是JSONP的一个应用
$.getJSON("http://example.com/api", function(data){})
CORS “跨域资源共享”(Cross-origin resource sharing)
允许JavaScript代码向另一个域名发出XMLHttpRequest请求,从而克服了传统上Ajax只能在同一个域名下使用的限制(same origin security policy)
//检查浏览器是否支持的代码如下
var request = new XMLHttpRequest();
if("withCredentials" in request) {
}
服务器回应的都有一个:Access-Control-Allow-Origin头信息.
Fetch API
Ajax操作所用的XMLHttpRequestRquest对象,已经有十多年的历史了,它的API设计并不是很好,输入、输出、状态都在同一个接口管理,容易出现混乱的代码.Fetch API是一种新规范,用来取代XMLHttpRequest对象.它主要有两个特定,一是简化接口,将API分散在几个不同的对象上,二是返回Promise对象,避免嵌套的回调函数.
检查浏览器是否部署了这个API的代码如下:
if (fetch in window){
//支持
}else {
//不支持
}
fetch API简单例子
var URL = 'http://some/path';
fetch(URL).then(function(response) {
return response.json();
}).then(function(json) {
someOperator(json);
});
上面代码向服务器请求JSON文件,获取后再做进一步处理.
function reqListener() {
var data = JSON.parse(this.responseText);
console.log(data);
}
function reqError(err) {
console.log('Fetch Error : -S', err);
}
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();
Fetch操作
fetch('./api/some.json')
.then(function(response) {
if(response.status !== 200){
console.log('请求失败,状态码: ' + response.status);
return;
}
response.json().then(function(data) {
console.log(data);
});
}).catch(function(err){
console.log('出错: ', err);
});
因为HTTP请求返回的response对象是一个Stream对象,所以需要使用response.json方法转为JSON格式,不过这个方法返回的是一个Promise对象。
* fetch()*
fetch方法的第一个参数可以是URL字符串,也可以是后文要讲到的Request对象实例.Fetch方法返回一个Promise对象,并将一个response对象传给回调函数.
发出POST请求的写法如下:
fetch("http://www.example.org/submit.php", {
method: "POST",
header: {
"content-Type": "application/x-www-form-urlencoded"
},
body: "firstName=nik&sdfs=blue&password=sdfs"
}).then(function(res) {
if(res.ok) {
console.log("Perfect!your settings are saved");
} else if(res.status == 401) {
console.log("oops,You are not authorized.");
}
},function(e) {
console.log("Error submitting form!");
});
Headers
Fetch API引入三个新的对象(构造函数): Header,Request和Response.
reqHeaders = new Headers({
"Content-Type": "text/plain",
"Content-Length": content.length.toString(),
"x-Custom-Header": "ProcessThisImmediately"
});
//headers实例构造Response方法
var response = new Response(
JSON.stringify({photos: {photo: []}}),
{'status': 200, headers: headers}
);
response.json().then(function(json) {
insertPhotos(json);
});
Request
//Request对象用来构造HTTP请求
var req = new Request('/index.html');
req.method //"GET"
req.url //"http://example.com/index.html"
//Request对象的第二个参数,表示配置对象
var uploadReq = new Request("/uploadImage", {
method: "POST",
headers: {
"Content-Type": "image/png",
},
body: "image data"
});
Response
- status:整数值,表示状态码(比如200)
- statusText:字符串,表示状态信息,默认是“OK”
- ok:布尔值,表示状态码是否在200-299的范围内
- headers:Headers对象,表示HTTP回应的头信息
- url:字符串,表示HTTP请求的网址
- type:字符串,合法的值有五个basic、cors、default、error、opaque。basic表示正常的同域请求;cors表示CORS机制的跨域请求;error表示网络出错,无法取得信息,status属性为0,headers属性为空,并且导致fetch函数返回Promise对象被拒绝;opaque表示非CORS机制的跨域请求,受到严格限制。
Response对象还有两个静态方法。
- Response.error() 返回一个type属性为error的Response对象实例
- Response.redirect(url, status) 返回的Response对象实例会重定向到另一个URL
body属性
Request对象和Response对象都有body属性,表示请求的内容。body属性可能是以下的数据类型。
- ArrayBuffer
- ArrayBufferView (Uint8Array等)
- Blob/File
- string
- URLSearchParams
- FormData
Request对象和Response对象都提供以下方法,用来读取body。
- arrayBuffer()
- blob()
- json()
- text()
- formData()
Request对象和Response对象都有bodyUsed属性,返回一个布尔值,表示body是否被读取过。
如果希望多次使用body属性,可以使用Response对象和Request对象的clone方法。