AJAX 是什么 ?
AJAX是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的 异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。
它不是一种单一的技术,而是一种使用现有技术集合的方法。它最常见的实现是使用 XMLHttpRequest (XHR) 对象。 特点:
是最早的异步请求解决方案
可以与服务器交换数据并更新部分网页内容,而无需重新加载整个页面
使用回调函数处理响应
不支持 Promise
而我们现在要使用基于 Promise 来实现 ajax 请求
什么是 Promise ?
Promise 是 JavaScript 中用于处理异步操作的对象,有 Pending、Fulfilled、Rejected 三种状态且不可逆转,通过链式调用及相关方法让异步代码编写更优雅、易维护,常用于网络请求、文件读取等多种异步场景。
如何手写 ?
王者写法
要实现基于 Promise 的 AJAX 请求封装,可以使用原生 JavaScript 提供的 XMLHttpRequest 来进行网络请求,并通过返回 Promise 对象来管理异步操作。
这样可以更好地处理异步请求的回调,使代码更加简洁和易读。
const getJSON = function(url){
return new Promise((resolve,reject)=>{
/*
这段代码的目的是为了创建一个XMLHttpRequest对象,用于发送HTTP请求。
由于不同的浏览器环境对XMLHttpRequest的支持不同,这段代码使用了条件运算符来进行兼容性处理:
XMLHttpRequest 是现代浏览器支持的对象,用于创建一个新的XMLHttpRequest实例。
ActiveXObject('Microsoft.XMLHTTP') 是用于在旧版本的Internet Explorer中创建XMLHttpRequest对象的替代方案。
不能直接使用 new XMLHttpRequest() 的原因是,旧版本的Internet Explorer(IE 5 和 IE 6)不支持这个构造函数,
而需要使用 ActiveXObject 来创建XMLHttpRequest对象。通过这种方式,代码可以在更多浏览器环境中正常工作。
*/
const xhr = XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject('Microsoft.XMLHTTP') //微软推出 , 核心对象
//是否异步
xhr.open("GET",url,true) //传入这第三个参数是为了指定请求是否异步执行,true表示异步
xhr.onreadystatechange = function(){
if(xhr.readyState !== 4 ) return; // 为什么要判断不等于4 ? 因为readyState为4表示请求已完成
// 304 状态码 ? Not Modified
// 第一次查找 200 后端开销耗时
// 后来 只要数据没有变化 ,没有必要再去查数据库
// 304 告诉我们 , 直接使用本地的缓存即可访问到数据
if(xhr.status == 200 || xhr.status === 304 ){ // 为什么要判断200和304 ? 200表示请求成功,304表示资源未修改,可以直接使用缓存
resolve(xhr.responseText)
}else{
reject(new Error(xhr.responseText))
}
}
xhr.send()
})
}
getJSON('https://api.github.com/orgs/lemoncode/members')
.then(data => {
console.log(JSON.parse(data))
})
其他写法
在实际开发中,可以使用 Fetch API 来替XMLHttpRequest,因为它更加强大且语法更简洁。
Fetch API 本身返回一个 Promise,处理起来非常方便:
如果是使用 fetch 来实现 :
可以这样(考虑的参数更多 , 上面写法也可以)
function getJSON(method, url, data = null) {
const options = { method };
if (data) {
options.headers = { 'Content-Type': 'application/json' };
options.body = JSON.stringify(data);
}
return fetch(url, options)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
});
}
// 使用示例
getJSON('GET', 'https://jsonplaceholder.typicode.com/posts')
.then(response => {
console.log('Success:', response);
})
.catch(error => {
console.error('Error:', error);
});