qs
$npm i qs
- qs是帮我们处理传参格式的类库
- Qs.stringify 对象转成‘age=12&name=xx’这种格式的字符串
- Qs.parse 把上面那种格式的字符串转成对象
axios
api http://www.axios-js.com/
axios是基于Promise封装的Ajax类库(真实项目中最常用的)
安装依赖
npm i axios
@1.基于axios发送请求(每当发送一次请求,返回的结果都是Promise实例)
//GET请求 传参 可以自己URL拼接,也可以基于params指定传递的参数信息
axios({
method: 'get',
url: '1.json',
params: {
name: 'xxx',
}
}).then(function(response){
console.log(response);
});
axios.get('./1.json?id=1').then(res => {
console.log(res);
/*
config 基本配置
data 后台拿到的数据 响应主体信息
headers 响应头信息
request 原生xhr实例
status HTTP状态码
statusText 状态描述
*/
});
//POST请求传参,基于DATA把信息通过请求主体传递给服务器(默认会把DATA中的内容转换为JSON格式的字符串传递给服务器,而不是JQ中看到的xxx=xxx&xxx=xxx)
axios({
method: 'post',
url: '1.json',
data: {
name: 'xxx',
}
}).then(function(response){
console.log(response);
});
真实项目中我们使用AXIOS发送对应的请求,会基于快捷请求方法实现
- axios.get/post/delete/put/head/options()
- axios.get([URL],[OPTIONS]) [OPTIONS]中包含params负责传递信息值
axios.post([URL],[DATA],[OPTIONS]) 第二部分直接就是请求主体的信息
axios get&post传递参数
get传参
在路径后传第二个参数,是个对象,对象里面有params对象,参数放在params对象里
axios.get("./1.json", {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
post 传参
- 直接第二个参数就是传给后台的
- axios的POST系列请求,默认是把DATA对象,变为JSON格式的字符串传递给服务器【如果DATA不是纯粹对象,则Axios内部默认你写的是啥,传递给服务器的就是啥】
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response.data) //JSON对象 因为默认responseType: 'json' console.log(response); }) .catch(function (error) { console.log(error); });
2.支持的配置信息都有哪些常用的
url/baseURL 请求地址/请求地址的前缀
- transformRequest:function(data){//只针对于POST系列请求 【因为它是处理请求主体】把客户端传递给服务器的请求主体数据格式做特殊处理}
- 它可以接收到我们写的DATA值,我们就可以根据需要把DATA变为自己想要的格式,最后函数返回啥,我们最后发送给服务器的就是啥
- 如果我们把格式处理好,Asios内部会识别到我们处理完的格式,它会自动去修改请求头中Content-Type类型【可能不完全准确】比如JSON格式的字符串
- headers:{} 自定义请求头信息
- data:{} POST请求传参
- timeout:1000 设置超时时间
- withCredentials:false; 在CORS跨域中设置是否允许携带资源凭证
- responseType: ‘json’, // 把从服务器获取的数据格式转换为指定的格式 服务器内部已经做了处理
- 设置服务器返回的状态码介于什么范围之间算是请求成功,成功触发THEN 失败触发CATCH
validateStatus: function (status) {
return status >= 200 && status < 300; // default
},配置参数 【第三个参数就是配置信息】
transformRequest 传递给服务器的请求主体信息
headers 请求头
//axios.post([URL],[DATA],[OPTIONS]) axios.post('./data.json', { name: 'zhufeng', age: 11 }, { headers: { "Content-Type": "application/x-www-form-urlencoded" //配置信息 }, transformRequest: data => { //data就是传递给服务器的请求主体信息{在这我们可以根据需要 把信息变为服务器需要的数据格式} //需求把DATA对象中的信息变为URLENCODED格式 if (data !== null && typeof data === "object") { /!* let str = ``; for (let key in data) { if (!data.hasOwnProperty(key)) break; str += `&${key}=${data[key]}`; } str = str.substring(1); return str; *!/ // Qs.stringify就是把一个对象变为URLENCODED格式的数据 return Qs.stringify(data); } return data; } });
配置默认值
// baseURL统一配置基本地址 axios.defaults.baseURL = 'http://liuqi.cn1.utools.club'; // 统一配置请求头 // headers.post给post请求增加请求头 // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; // headers.common给所有请求都增加请求头 axios.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded'; // transformRequest在post请求之前,调用来处理传参,返回值会放请求体里传给后台 axios.defaults.transformRequest = function (data, headers) { // 统一处理参数的地方 return Qs.stringify(data); }; // baseURL拼上/user/add的接口 axios.post('/user/add', {id: 21, name: 34}).then(res => {}); // baseURL拼上127.0.0.1:8888/user/add的接口 // axios.post('127.0.0.1:8888/user/add', {id: 21, name: 34}).then(res => {}); // 当地址是以http或HTTPS开头,会用自己的地址,跟baseURL没关系了 // axios.post('http://127.0.0.1:8888/user/add', {id: 21, name: 34}).then(res => {}); // axios.post('/user/login', {id: 21, name: 34},{ // baseURL:'http://127.0.0.1:8899' // }).then(res => {});
把公共的配置信息提前处理 {Axios 的二次配置}
url 地址每次加前缀比较麻烦 所以提取处理出来
- BASE-URL是每次发送请求设置的公共前缀 ```javascript // BASE-URL是每次发送请求设置的公共前缀 axios.defaults.baseURL = ‘http://127.0.0.1:8888‘; // axios.defaults.withCredentials = true;//跨域 允许携带凭证 axios.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded’; axios.defaults.transformRequest = data => Qs.stringify(data);//只支持POST axios.defaults.validateStatus = status => { return /^(2|3)\d{2}$/.test(status);//以2或者3开头都算成功 }; // 请求拦截器(在客户端把信息传递给服务器的时候 GET/POST),中间拦截一下(在拦截的时候可以自己在而外修改配置点信息) // 请求拦截器:发生在请求发送之前的最后一步 axios.interceptors.request.use(config => { // console.log(config); // config.headers[‘Content-Type’] = ‘application/x-www-form-urlencoded’; // 真实项目中我们可能会在请求拦截器中,设置自定义请求头,把TOKEN信息传递给服务器,这样做接口的合法性验证 return config; });
// 响应拦截器(在获取服务器返回结果和执行自己的.THEN之间处理的事情) axios.interceptors.response.use(result => { // 成功 return result.data; //=>只把响应主体信息返回(在自己.THEN的时候获取的只有主体信息了) }, reason => { return Promise.reject(reson); // 失败 // 在此处统一做错误处理(和服务器通信了,服务器返回的是4/5开头状态码,此时我们根据不同的状态码统一做提示即可;连通信都没有通信,此时说明网络有问题,我们做对应的提示); });
<a name="ct0tg"></a>
# 自己基于js封装axios
```javascript
// 把my_axios作为普通对象,增加defaults属性,加入一个默认的baseURL
my_axios.defaults = {baseURL: ''};
function my_axios(options) {
let {method = 'get', url, params, data, headers} = options;
return new Promise((resolve, reject) => {
// 统一转大写
method = method.toUpperCase();
// 处理地址
if (url.indexOf('http') !== 0) {
url = my_axios.defaults.baseURL + url;
}
// 处理get请求传参
if (method === 'GET') {
if (url.indexOf('?') > -1) {
url += '&' + Qs.stringify(params);
} else {
url += '?' + Qs.stringify(params);
}
}
let xhr = new XMLHttpRequest();
xhr.open(method, url);
// 设置请求头
Object.keys(headers).forEach(key => {
xhr.setRequestHeader(key, headers[key]);
});
xhr.onreadystatechange = function () {
if (
xhr.readyState == 4 &&
xhr.status >= 200 &&
xhr.status < 400
) {
let text = xhr.responseText;
let data = {
data: JSON.parse(text), //后台拿到的参数
request: xhr, //xhr实例
config: '', //axios配置
headers: '', //响应头
status: xhr.status, //HTTP状态码
statusText: xhr.statusText, //状态描述
};
resolve(data);
} else if (xhr.readyState == 4 && xhr.status >= 400) {
reject(xhr.response);
}
};
xhr.send(data ? JSON.stringify(data) : null);
});
}
// baseURL统一配置基本地址
my_axios.defaults.baseURL = '';
my_axios({
method: 'get',
url: './1.json',
params: {id: 3},
headers: {
'Content-Type': 'application/json;',
},
}).then(res => {
console.log(res);
});
fetch
fetch和axios的区别
他俩都是发送请求的
axios是基于promise封装的ajax类库
fetch是浏览器原生的API
传参字段不一样,axios是放在params或者data里,fetch是放在body里
node环境中不支持fetch,需要引入node-fetch文件才能支持
axios中的配置和拦截器等功能,fetch中都没有。
fetch('./1.json', {
method: 'GET',
headers: {},
// 必须是字符串
// body: JSON.stringify({id:1})
}).then(res => {
//返回的是response对象 response.body是返回的信息是个二进制流 所以要转成json
// 需要使用fetch提供的json方法转化一下
// .json和.text()方法只能执行一次
// console.log(res.json());
return res.json();
}).then(res=>{
console.log(res);
})
fetch('./data.json').then(response => {
// response中包含了服务器返回的信息:响应主体信息response.body「ReadableStream可读流信息」,我们需要把可读流信息变为指定的格式
// + Response.prototype.json/text/blob/arrayBuffer...
// + 执行这些方法中的任何一个,返回结果都是一个promise实例:如果可以把响应主体信息正常转换为指定的格式,则promise的状态是fulfilled、值是转换为的数据内容,如果不能正常转换,则状态是失败的...
// + 一但执行了其中的一个方法,再执行其他方法,会出问题
return response.json();
}).then(value => {
console.log(value);
});