一、ajax
- AJAX:异步 JavaScript 和 XML,用来发送异步请求。有了Ajax之后,在无需重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
Ajax是基于现有的Internet标准,联合使用了XMLHttpRequest,JS/DOM,CSS,XML等技术。
它有个较大的缺陷就是业务逻辑需要在回调函数中执行,如果多个请求存在依赖关系,就会产生回调地狱问题,对读写理解困难。
XHR对象常用方法
(1)XMLHttpRequest.open()
初始化一个请求。已激活的请求再次调用此方法时,相当于调用了abort(),会中断上一个请求。
当设置了async(第三个参数)true之后,请规定onreadystatechange事件中的就绪状态执行响应函数。
(2)XMLHttpRequest.send()
向服务器发送http请求。如果open()中定义的是异步请求,则此方法会在请求发起后立刻返回;如果是同步,则在请求返回后才执行。
(3)XMLHttpReqeust.abort()
当请求已经发出,则立刻中断请求。将readystate设置为0,立刻调用onreadystatechange方法执行回调函数。
(4)XMLHttpRequest.setReqeustHeader()
用于给HTTP请求增加自定义请求头,在open()之后,send()之前定义。设置多个相同的请求头,在发起时会进行合并。
(5)XMLHttpRequest.getResponseHeader()
根据名称获取HTTP请求头,如果需要一次请获取全部,请使用getAllHeetResponseHeader()方法。
XMLHTTP.readyState的五种状态
0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了
- (0)未初始化
此阶段确认XMLHttpRequest对象是否创建,并为调用open()方法进行未初始化作好准备。值为0表示对象已经存在,否则浏览器会报错--对象不存在。
- (1)载入
此阶段对XMLHttpRequest对象进行初始化,即调用open()方法,根据参数(method,url,true)完成对象状态的设置。并调用send()方法开始向服务端发送请求。值为1表示正在向服务端发送请求。
- (2)载入完成
此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能直接在客户端使用。值为2表示已经接收完全部响应数据。并为下一阶段对数据解析作好准备。
- (3)交互
此阶段解析接收到的服务器端响应数据。即根据服务器端响应头部返回的MIME类型把数据转换成能通过responseBody、responseText或responseXML属性存取的格式,为在客户端调用作好准备。状态3表示正在解析数据。
- (4)完成
此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。值为4表示数据解析完毕,可以通过XMLHttpRequest对象的相应属性取得数据。
-
- 概而括之,整个XMLHttpRequest对象的生命周期应该包含如下阶段:
创建-初始化请求-发送请求-接收数据-解析数据-完成
- 概而括之,整个XMLHttpRequest对象的生命周期应该包含如下阶段:
封装一个原生的Ajax请求
ajaxRequest(method, url, data, callback) {
let xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
if (method.toLocalCase() === "get") {
url = url + this.getParams(data);
xhr.open(method, url, true);
xhr.send();
} else { // post
xhr.open(method, url, true);
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
data ? xhr.send(data) : xhr.send()
}
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.state === 200) {
// 约定返回字符串格式,如是xml格式使用responseXML
callback(xhr.responseText);
} else {
reject(new Error(xhr.statusText))
} else {
if (xhr.readyStatue === 0) {
alert("请求已取消");
}
}
}
}
buildGetParams(obj) {
if (!obj || obj.keys.length === 0) return '';
let str = Object.keys(obj).reduce(function(prev, cur, index) {
if (index === 1) {
prev = prev + '=' + obj[prev]
}
return prev + (prev ? '&' : '') + cur.toString() + '=' + obj[cur]
})
}
二、Promise
Promise对象由ES6提供,它表示一个尚未完成且预计在未来完成的异步操作。Promise 仅仅是一种决定异步任务状态确定时会出现什么结果的技术。它本身并不提供异步请求功能,更不能替代Ajax。
Promise将异步请求的回调操作,改成了同步的链式写法,最直观的就是使用Promise处理ajax请求时,可以解决回调地狱问题;另外,Promise封装了统一的接口,使得控制异步操作变得更加简单。
但它的缺点也比较明显,发起的Promise无法取消中断,其次,如果不设捕获异常的回调函数,Promise内部抛出的错误无法反应到外部出来。另外,未执行完成的Promise也无法确定是刚开始还是即将结束(即ajax的readyState在哪个过程)。
创建Promise
let promise = new Promise((resolve, reject) => {
// 执行结束需要使用resolve或reject将结果返回
})
Promise的基本API
Promise有三种状态,分别是 pending:执行状态、fulfilled:已成功、rejected:已失败。
pending只能改变为fulfilled或rejected其中一种,且状态一旦改变,将凝固不再改变。即使再次修改,该操作也会被忽略。
使用Promise写法实现Ajax请求
getRequest(url) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.send();
xhr.onreadystatechange() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(new Error(xhr.statusText))
}
}
}
})
}
// 调用
this.getRequest("http://demo-domain:8080?name=test").then(resp => {
console.log(resp)
})
Axios
Axios是一个基于Promise的http库,支持node端和浏览器端,支持拦截器、自定义请求头、取消请求等高级配置,支持自动转换JSON,也支持npm包的使用。总之,优点多多,用就对了…
自定义axios实例
let request = axios.create({
baseURL: 'http://some-domain.com/api/',
timeout: 1000,
headers: { 'X-Custom-Header': 'footbar' }
})
常用axios的请求配置
- 以下配置中,只有 url 是必须的,如果没有配置method,将默认使用get方法。
- url: ‘/user’ 用户请求服务器资源的 URL
- method: ‘post’ 创建请求时使用的方法
- baseURL: ‘http://demo-domain:8080/api/’ 自动加在URL(非绝对路径时)前的路径
- headers: { ‘x-Requested-With’: ‘XMLHttpRequest’ } 自定义请求头
- params: { ‘ID’: ‘12345’ } 与请求一起发送的URL参数,当method指定为GET时使用
- data: { ‘name’: ‘zhangfs’ } 请求主体参数,用于PUT,POST,PATCH方法
- timeout: 8000 请求超时时间,0表示无超时;超过时间请求被中断
- withCredentials: false 请求跨域时是否需要使用凭证
- auth: { username: ‘zhangfs’ } 用于HTTP基础验证,将复写Authorization头
- proxy: {
host: ‘127.0.0.1’,
port: 9000,
} 代理服务器的主机名与端口,将设置Proxy-Authoriation - cancelToken: new CancelToken(function(cancel) { … }) 指定取消请求的cancel token
请求拦截器
- 在请求或响应被 then 或 catch 处理前拦截它们。如果自定义了axios实例如request,则使用 request.interceptors.xxx
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
标签:Axios,XMLHttpRequest,请求,url,send,xhr,Promise,搞懂
From: https://www.cnblogs.com/maxiaohu/p/16807495.html