基于Promise发送原生Ajax请求
// 基于Promise发送原生Ajax请求
function queryData(url) {
//resolve请求成功的回调函数 reject请求失败的回调函数
var p = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState != 4) return;
if(xhr.readyState == 4 && xhr.status == 200) {
// 处理正常的情况
resolve(xhr.responseText);
}else{
// 处理异常情况
reject('服务器错误');
}
};
xhr.open('get', url);
xhr.send(null);
});
return p;
}
// 发送多个ajax请求并且保证顺序
queryData('http://localhost:3000/data')
.then(function(data){
console.log(data)
return queryData('http://localhost:3000/data1');
})
//这里的then指向的是上面return的promise对象
.then(function(data){
console.log(data);
return 'hello';
})
//这里的then指向的是上面return返回新创建的promise对象
.then(function(data){
console.log(data)
});
异步任务API
.then(function(data){}) 任务成功执行的函数
.catch(function(error){}) 任务出错执行的函数
.finally(function(){}) 无论成功出错都会执行的函数
.race([a,b,..]) 参数是一个数组,数组是promise对象,该方法是执行数组内所有的异步函数,返回最快执行完的一个promise对象结果
.all([a,b,..]) 参数是一个数组,数组是promise对象,该方法需要所有的异步函数执行完才会返回结果
var p1 = queryData('http://localhost:3000/a1');
var p2 = queryData('http://localhost:3000/a2');
var p3 = queryData('http://localhost:3000/a3');
Promise.all([p1,p2,p3]).then(function(result){
console.log(result)
})
Promise.race([p1,p2,p3]).then(function(result){
console.log(result)
})
异步函数返回的值是promise对象,如果希望得到返回的数据,可以使用async await
Fetch(用法跟promise类似)
Fetch API是新的ajax解决方案
Fetch会返回Promise fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象
//使用Express框架搭建服务器
const express = require('express')
const app = express()
// Express框架默认使用body-parser作为请求体解析中间件
const bodyParser = require('body-parser')
// 处理静态资源
app.use(express.static('public'))
// 处理参数
app.use(bodyParser.json());
// false表示使用系统模块querystring来处理,也是官方推荐的,true即使用第三方模块
app.use(bodyParser.urlencoded({ extended: false }));
// 设置允许跨域访问该服务
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Headers', 'mytoken');
next();
});
//服务器端get请求接口一
app.get('/fdata', (req, res) => {
res.send('Hello Fetch!')
})
/*
//客户端请求代码
fetch('http://localhost:3000/fdata').then(function(data){
// text()方法属于fetchAPI的一部分,它返回一个Promise实例对象,用于获取后台返回的数据
return data.text();
}).then(function(data){
console.log(data);
})
*/
//服务器端get请求接口二
app.get('/books', (req, res) => {
// query是url的查询参数
res.send('传统的URL传递参数!' + req.query.id)
})
/*
//客户端请求代码
//GET参数传递-传统URL
fetch('http://localhost:3000/books?id=123', {
method: 'get'
})
.then(function(data){
//将返回值转换成字符串
return data.text();
}).then(function(data){
// 输出123
console.log(data)
});
*/
//服务器端get请求接口三
app.get('/books/:id', (req, res) => {
// params是参数名
res.send('Restful形式的URL传递参数!' + req.params.id)
})
/*
//客户端请求代码
//GET参数传递-restful形式的URL
fetch('http://localhost:3000/books/456', {
method: 'get'
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
*/
//服务器端delete请求接口
app.delete('/books/:id', (req, res) => {
res.send('DELETE请求传递参数!' + req.params.id)
})
/*
//客户端请求代码
//DELETE请求方式参数传递
fetch('http://localhost:3000/books/789', {
method: 'delete'
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
*/
//服务器端post请求接口一
app.post('/books', (req, res) => {
//这里的body是经过解析中间件处理得到的
res.send('POST请求传递参数!' + req.body.uname + '---' + req.body.pwd)
})
/*
//客户端请求代码
//POST请求传参
fetch('http://localhost:3000/books', {
method: 'post',
body: 'uname=lisi&pwd=123',
headers: {
//这里一定要设置类型 类型为:'uname=lisi&pwd=123'格式
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
*/
//服务器端post请求接口二
app.put('/books/:id', (req, res) => {
res.send('PUT请求传递参数!' + req.params.id + '---' + req.body.uname + '---' + req.body.pwd)
})
/*
//客户端请求代码
//POST请求传参
fetch('http://localhost:3000/books', {
method: 'post',
body: JSON.stringify({
uname: '张三',
pwd: '456'
}),
headers: {
//这里设置的参数类型是json格式
'Content-Type': 'application/json'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
*/
//服务器端put请求接口
app.put('/books/:id', (req, res) => {
res.send('PUT请求传递参数!' + req.params.id + '---' + req.body.uname + '---' + req.body.pwd)
})
/*
//客户端请求代码
// PUT请求传参
fetch('http://localhost:3000/books/123', {
method: 'put',
body: JSON.stringify({
uname: '张三',
pwd: '789'
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(function(data){
return data.text();
}).then(function(data){
console.log(data)
});
*/
Axios
基于promise用于浏览器和node.js的http客户端
支持浏览器和node.js
支持promise
能拦截请求和响应
自动转换JSON数据
能转换请求和响应数据
axios基础用法
get和 delete请求传递参数
通过传统的url 以 ? 的形式传递参数
restful 形式传递参数
通过params 形式传递参数
post 和 put 请求传递参数
通过选项传递参数
通过 URLSearchParams 传递参数
//服务器端get接口一
// query查询参数
app.get('/axios', (req, res) => {
res.send(req.query.id)
})
/*
//客户端get请求传参方式一
axios.get('http://localhost:3000/axios?id=123').then(function(ret){
console.log(ret.data)
})
*/
//服务器端get接口二 params参数
app.get('/axios/:id', (req, res) => {
res.send(req.params.id)
})
/*
//客户端get请求方式二
axios.get('http://localhost:3000/axios/123').then(function(ret){
console.log(ret.data)
})
*/
/*
//客户端get请求方式三
axios.get('http://localhost:3000/axios', {
params: {
id: 789
}
}).then(function(ret){
console.log(ret.data)
})
*/
//服务器端delete接口
app.delete('/axios', (req, res) => {
res.send(req.query.id)
})
/*
客户端delete请求方式
axios delete 请求传参
axios.delete('http://localhost:3000/axios', {
params: {
id: 111
}
}).then(function(ret){
console.log(ret.data)
})
*/
//服务器端post接口
app.post('/axios', (req, res) => {
res.send(req.body.uname + '---' + req.body.pwd)
})
/*
//客户端post请求方式一 json格式
axios.post('http://localhost:3000/axios', {
uname: 'lisi',
pwd: 123
}).then(function(ret){
console.log(ret.data)
})
//客户端post请求方式二 字符串格式 通过URLSearchParams 传递参数
var params = new URLSearchParams();
params.append('uname', 'zhangsan');
params.append('pwd', '111');
axios.post('http://localhost:3000/axios', params).then(function(ret){
console.log(ret.data)
})
*/
//服务器端put接口
app.put('/axios/:id', (req, res) => {
res.send(req.params.id + '---' + req.body.uname + '---' + req.body.pwd)
})
/*
//客户端post请求方
axios.put('http://localhost:3000/axios/123', {
uname: 'lisi',
pwd: 123
}).then(function(ret){
console.log(ret.data)
})
*/
axios 全局配置
// 配置请求的基准URL地址
axios.defaults.baseURL = 'http://localhost:3000/';
// 配置 超时时间
axios.defaults.timeout = 2500;
// 配置请求头信息
axios.defaults.headers['mytoken'] = 'hello';
//因为配置的基准url地址,此处url不用重复写
axios.get('axios-json').then(function(ret){
console.log(ret.data.uname)
})
axios 拦截器
1、请求拦截器
请求拦截器的作用是在请求发送前进行一些操作
例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易
2、响应拦截器
响应拦截器的作用是在接收到响应后进行一些操作
例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页
// 请求拦截器
axios.interceptors.request.use(function(config) {
// 任何请求都会经过这一步 在发送请求之前做些什么
//设置请求头信息
config.headers.mytoken = 'nihao';
// 这里一定要return 否则配置不成功
return config;
}, function(err){});
// 响应拦截器
axios.interceptors.response.use(function(res) {
//在此处可以对响应的内容做处理,如下将返回res的data内容。
var data = res.data;
return data;
}, function(err){});
async 和 await
async作为一个关键字放到函数前面
任何一个 async 函数都会隐式返回一个 promise
await 关键字只能在使用 async 定义的函数中使用
await后面可以直接跟一个 Promise实例对象
await函数不能单独使用
async/await 让异步代码看起来、表现起来更像同步代
//服务器端接口
app.get('/async1', (req, res) => {
res.send('hello')
})
app.get('/async2', (req, res) => {
if(req.query.info == 'hello') {
res.send('world')
}else{
res.send('error')
}
})
// 客户端请求方式
async function queryData() {
var info = await axios.get('async1');
var ret = await axios.get('async2?info=' + info.data);
return ret.data;
}
queryData().then(function(data){
console.log(data)
})
来源:oschina
链接:https://my.oschina.net/u/4139437/blog/3168201