AJAX
AJAX就是浏览器赋予JS的一套API,通过这套API能够使JS具备网络通信的能力
历史
浏览器本身就具备网络通信的能力,但在早期,浏览器并没有把这个能力开放给JS。
最早是微软在IE浏览器中把这一能力向JS开放,让JS可以在代码中实现发送请求,这项技术在2005年被正式命名为AJAX(Asynchronous Javascript And XML)
IE使用了一套API来完成请求的发送,这套API主要依靠一个构造函数完成。该构造函数的名称为 XMLHttpRequest
,简称为 XHR
,所以这套API又称之为 XHR API
由于 XHR API
有着诸多缺陷,在HTML5和ES6发布之后,产生了一套更完善的API来发送请求。这套API主要使用的是一个叫做 fetch
的函数,因此这套API又称之为 Fetch API
无论是 XHR
还是 Fetch
,它们都是实现ajax的技术手段,只是API不同。
XHR API
var xhr = new XMLHttpRequest(); //创建发送请求的对象
xhr.onreadystatechange = function(){ //当请求状态发生改变时运行的函数
// xhr.readyState: 一个数字,用于判断请求到了哪个阶段
// 0: 刚刚创建好了请求对象,但还未配置请求(未调用open方法)
// 1: open方法已被调用
// 2: send方法已被调用
// 3: 正在接收服务器的响应消息体
// 4: 服务器响应的所有内容均已接收完毕
// xhr.responseText: 获取服务器响应的消息体文本
// xhr.getResponseHeader("Content-Type") 获取响应头Content-Type
}
xhr.open("请求方法", "url地址"); //配置请求
xhr.setRequestHeader("Content-Type", "application/json"); //设置请求头
xhr.send("请求体内容"); //构建请求体,发送到服务器,如果没有请求体,传递null
封装ajax
function ajax(options) {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
options.success(xhr.responseText);
} else {
options.error(xhr.responseText);
}
}
}
xhr.open(options.method, options.url);
xhr.send();
}
//调用这个函数,以发送一个简单的 GET 请求:
ajax({
method: 'GET',
url: 'https://example.com/data',
success: function(response) {
console.log('请求成功', response);
},
error: function(error) {
console.log('请求失败', error);
}
});
promise封装Ajax
function ajax(url, method, data) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(new Error('Something went wrong'));
}
};
xhr.onerror = function() {
reject(new Error('Network Error'));
};
xhr.send(JSON.stringify(data));
});
}
ajax('https://jsonplaceholder.typicode.com/todos/1', 'GET')
.then(function(data) {
console.log(data);
})
.catch(function(error) {
console.error(error);
});
Fetch API
const resp = await fetch('url地址', { // 请求配置对象,可省略,省略则所有配置为默认值
method: '请求方法', // 默认为GET
headers: { // 请求头配置
'Content-Type': 'application/json',
'a': 'abc'
},
body: '请求体内容' // 请求体
}); // fetch会返回一个Promise,该Promise会在接收完响应头后变为fulfilled
resp.headers; // 获取响应头对象
resp.status; // 获取响应状态码,例如200
resp.statusText; // 获取响应状态码文本,例如OK
resp.json(); // 用json的格式解析即将到来的响应体,返回Promise,解析完成后得到一个对象
resp.text(); // 用纯文本的格式解析即将到来的响应体,返回Promise,解析完成后得到一个字符串
Ajax与XHR和fetch的关系
Ajax(Asynchronous JavaScript and XML)是一种使用 JavaScript 发送异步 HTTP 请求并更新网页内容的技术。Ajax 的核心是 XMLHttpRequest(XHR)对象,它允许我们在后台发送 HTTP 请求并处理响应,而不必刷新整个网页。
XHR 是 Ajax 最初的实现方式,它使用 XMLHttpRequest 对象来发送和接收数据,然后使用 JavaScript 更新网页内容。XHR 允许您使用多种 HTTP 方法,例如 GET、POST、PUT、DELETE 等,还允许发送表单数据、文件等不同类型的数据。XHR 对象的 API 很强大,但使用起来比较繁琐,需要手动处理异步回调和错误。
fetch 是 ES6 引入的新的 API,它提供了一种简单、灵活的方式来发送异步 HTTP 请求。fetch 返回一个 Promise 对象,允许您使用链式语法来处理响应,而不需要手动处理异步回调。fetch 的 API 设计比较简洁,但它缺乏一些 XHR 提供的高级功能,例如上传进度监测、取消请求等。
XHR 和 fetch 的主要区别在于它们的 API 设计和用法。XHR 更强大,但更复杂,适用于需要精细控制请求过程的场景。fetch 更简单、易用,适用于一般的异步请求场景。不过,需要注意的是,fetch 有一些浏览器兼容性问题,需要进行适当的处理。
XHR获取进度
用Ajax
发送HTTP请求时,可以通过XMLHttpRequest
对象提供的onprogress
事件来获取请求的进度信息。该事件会在请求发送过程中周期性地触发,通常用于实时更新请求的进度。
下面是一个使用Ajax
获取进度信息的示例:
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.onprogress = function (event) {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
console.log(`Progress: ${percentComplete}%`);
}
};
xhr.send();
在上面的示例中,XMLHttpRequest
对象通过open
方法指定请求的方法和URL,然后使用onprogress
事件来监听请求的进度信息。在onprogress
事件中,可以通过event.loaded
和event.total
属性来获取已加载和总共需要加载的数据量,从而计算出请求的进度百分比。
需要注意的是,onprogress
事件在请求发送过程中会周期性地触发,因此可能会频繁地打印进度信息。如果需要更细粒度的控制,可以通过设置请求头或使用其他技术来实现。
fetch搭配await使用
使用await fetch 会获得已决状态的值,res或err
而单独使用fetch,本身也是异步的返回promise.then进行回调处理