ajax是什么?
如果google一波,你能搜到很多专业的解答,但是这里只通俗的讲一下,就是一个能让你以异步的方式去请求数据的方案。从而获得无等待,无刷新的优秀体验。
ajax怎么用?
- 说到ajax,就不得不提XMLHttpRequest对象,通过这个对象创建的实例,你就可以发起神奇的ajax请求了。
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){
console.log(xhr.responseText);
}else{
console.log('ajax failed!');
}
}
}
xhr.send(null);
这样就完成了一个最简单的ajax请求。
ajax请求是一个异步请求。如果你直接将上面那段代码放在一个函数里面,将console.log(xhr.responseText)改成return xhr.responseText,调用函数后你是拿不到真正的返回值的。你拿到的是undefined。因为这个是一个异步请求。如果你想封装到一个方法中,可以这样写:
function getJSON(url){
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
return resolve(JSON.parse(xhr.responseText));
}else{
return reject('Get request failed');
}
}
}
xhr.send(null);
})
}
通过借助es6的Promise对象,可以以同步的方式执行异步的代码。当然,想实现这种效果的方式还有很多种,但是这里只是为了说明这是一个异步操作。
var data = getJSON('/server');
就能直接拿到相应的值并赋值给data。
XMLHttpRequest对象
readyState值 | 状态 | 描述 |
---|---|---|
xhr.readyState === 0 | unsent | open方法还未被调用 |
xhr.readyState === 1 | opened | send方法还未被调用 |
xhr.readyState === 2 | headers-received已获取响应头 | send方法已调用,响应头和响应状态已经返回 |
xhr.readyState === 3 | loading正在下载响应体 | 响应体下载中; responseText中已经获取了部分数据. |
xhr.readyState === 4 | done | 整个请求过程已经完毕. |
一般我们只关注xhr.readyState === 4的阶段,因为这个时候已经拿到完整的数据了。
onreadystatechange函数能够监听请求的状态值变化,所以我们可以通过这个方法,监听状态值 == 4的时机,然后拿到请求返回的内容。
实际使用中,通过这个实例可以发挥更多神奇的作用。比如:
- 实现文件上传进度条
function updateFile(){
var file = document.querySelect('input[type="file"]').files[0];
var form = new FormData();
form.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('post', '/serverURL', true);
xhr.onload = function(e){
console.log(e.responseText);
};
xhr.upload.addEventListener('progress', progressFun, false);
xhr.send(form);
}
function progressFun(e){
var progressBar = document.querySelect('#progressBar');
if(e.lengthComputable){
progressBar.max = e.total;
progressBar.value = e.loaded;
}
}
ajax实际使用中可能会遇到的问题
1. 最常见的问题:跨域
2. 状态值 == 200,但是没有拿到正确的内容
有的时候虽然请求成功了并返回,但是其实出错了,这个时候需要给xhr.onerror绑定事件,有的错误可能需要使用这个方法去捕获。
3. 本地文件发起请求可能报错
有的浏览器因为安全策略原因,限制了本地文件的ajax请求。可以搭建一个服务端环境发起请求,或者使用IE(IE貌似没有这个限制)。