原生JS实现AJAX
什么是Ajax
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),不是新的编程语言,而是一种使用现有标准的新方法,不重新加载整个页面的情况下更新部分页面
Ajax工作原理
XHR(XMLHttpRequiest)
创建XHR对象
新版本的浏览器都支持XHR对象,直接实例化即可var xhr = new XMLHttpRequest();
XHR请求
如果要将数据发送到服务器,使用XMLHttpRequest 对象的 open() 和 send() 方法
open(method, url, async)
- method:请求的类型;GET 或 POST
- url:文件在服务器上的位置
- async:true(异步)或 false(同步)
send(string)
- string:仅用于 POST 请求发送数据
GET请求
function load() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("box").innerHTML = xhr.responseText;
}
}
xhr.open('GET', '/promise.js', true);
xhr.send();
}
声明一个函数,函数中实例化一个XHR实例对象,当xhr的状态改变成相应的状态时,将请求到的文本插入HTML文档中
![QQ录屏20200818150134 00_00_00-00_00_30](https://cdn.easyremember.cn/img/QQ录屏20200818150134 00_00_00-00_00_30.gif)
POST请求过程相同,只是在send中加入要发送的数据
封装
每次请求都要写这一堆东西太过繁琐,将代码抽离出来作为单独的模块
var Ajax = {
get: function (url,callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
callback(xhr.responseText);
}
}
},
post: function (url, data, callback) {
var xhr = new XMLHttpRequest();
xhr.open('POSt', url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
callback(xhr.responseText);
}
}
xhr.send(data);
}
}
function load() {
Ajax.get('/promise.js', (res) => {
document.getElementById("box").innerHTML = res;
});
}
get请求传入url和callback,ststus变为200时触发callback
readystate
status
反馈内容
基于Promise封装
var Ajax = {
get: function (url) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status === 0)) {
resolve(xhr.responseText);
}
}
})
},
post: function (url, data) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('POSt', url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 0) {
resolve(xhr.responseText);
}
}
xhr.send(data);
})
}
}
function load() {
const p = Ajax.get('/promise.js').then(value => {
console.log(value);
}).catch(reason => {
console.log(reason);
})
}
把异步操作封装到Promise,调用起来相当方便,这样可以请求到数据,但判断状态如果加上else就会走else分支,目前没有找到原因