「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」
关于异步请求(XHR)
同步请求:当浏览器向服务器发送请求,发送成功之后,浏览器处于等待状态,等到服务器返回响应数据,浏览器接收数据并做相应处理后重新加载页面。
基于以上,当浏览器发送请求后就只能等待,无法执行别的事件,所以引入异步请求
异步请求:大部分浏览器内置了XMLHttpRequest对象,浏览器把请求交给了XMLHttpRequest,浏览器发送请求后,不需要等待响应,待服务端响应后,刷新页面局部内容。
关于Ajax
Ajax 全名是Asynchronous Javascript and XML(异步的Javascript与XML技术)
Axios
Axios是一个基于Promise用于浏览器和Node.js的http客户端
Axios 基于浏览器内置对象XML和Promise对象,通过node.js发起http请求;通过拦截器配置请求数据和转换响应数据并做相应处理,基于XML,因此也支持取消请求。
Axios请求的封装
// 需要引入axios
// 创建axios实例
const service = axios.create({
baseURL: process.env.BASE_API,
timeout: 15000
});
// 配置请求拦截器
service.interceptors.request.use(
config => {
// 统一网络请求的请求头
if (store.getters.token) {
config.headers['Authorization'] = "XXX";
}
return config;
},
error => {
// ...... 对错误信息进行统一处理
Promise.reject(error);
}
);
// 配置响应拦截器
service.interceptors.response.use(
response => {
// ...... 对响应数据进行统一处理
return response;
},
error => {
// ...... 对错误信息进行统一处理
return Promise.reject(error);
}
)
export default service
fetch
关于fetch的浏览器支持度,如下图,需要提醒的是,fetch不提供对IE的支持。
fetch提供一个JS接口,用于定义Request和Response对象。它基于Promise,但是对于服务端响应的404、500等状态码,fetch都把它标记为resolve,仅当网络故障或请求中断,才会标记为reject。
对于Response对象,需要做下.json()处理,来把HTTP响应解析为JSON数据
关于fetch无法跟Ajax一样中断请求的问题,浏览器现已开始对Abort API添加实验性支持。
fetch 现也还不支持超时控制,且跨域默认不会带cookie
跨域
说到异步请求的封装,那前端的跨域配置也是必须的了。
对于普通的跨域请求,服务端设置Access-Control-Allow-Origin即可。
对于需要带cookie的请求,前后端都需要设置,设置方法有:
- 对于
vue框架的跨域,可通过webpack配置文件,配置devServer,若需要支持websocket跨域,配置ws:true即可
devServer: {
proxy: {
'/api':{
target: APP_BASE_URL,
ws: true,
secure: false,// 如果是https接口,需要配置这个参数
changeOrigin: true
}
}
}
- 对于
nuxt框架的跨域,配置也是类似的nuxt.config.js文件中配置如下:
// 配置代理
axios: {
proxy: true
},
proxy: {
'/service': {
target: APP_BASE_URL
}
}
- 对于非
vue框架的跨域,可通过ng进行配置
server {
listen 8080;
server_name 127.0.0.1;
location / {
proxy_pass http://59.110.XXX.XXX;
client_max_body_size 10m; #表示最大上传10M,需要多大设置多大。
proxy_read_timeout 300s;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- 还有个方法,直接将
chrome浏览器设置成跨域浏览器,设置方法可以自行百度搜索~
async和await语法糖的使用
async和await是generator函数的语法糖,写法上替代了Promise回调函数。await意图等待Promise对象的状态被resolved,对于Promise状态被reject的情况,需要通过try catch来获取。写法如下:
async handleDelete(data) {
try {
await deleteBatch({ list: data });
this.$message.success('删除成功!');
} catch (e) {
// 处理请求失败的情况
this.$message.error('删除失败!');
}
},
async和await使用过程中需要注意的是,await必须在async函数的上下文中的。- 注意以下:多个异步 不同写法的执行情况:
async test() {
let p1 = getSwYw();
let p2 = getOrderNum({orderType: 0});
let p3 = checkActive();
try {
let res = await Promise.all([p1, p2, p3]);
console.log('成功', res)
} catch(e) {
console.log('失败', e)
}
}
这种写法:三个异步请求是并发执行的,如下图:
三个请求完成后才有结果输出,如下图:
async test() {
await getSwYw();
await getOrderNum({orderType: 0});
await checkActive();
console.log('成功');
},
这种写法: 三个异步请求是继发执行的,如下图:
跟上面的一样,3个请求完成后才会输出“成功”