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实例)

  1. //GET请求 传参 可以自己URL拼接,也可以基于params指定传递的参数信息
  2. axios({
  3. method: 'get',
  4. url: '1.json',
  5. params: {
  6. name: 'xxx',
  7. }
  8. }).then(function(response){
  9. console.log(response);
  10. });
  1. axios.get('./1.json?id=1').then(res => {
  2. console.log(res);
  3. /*
  4. config 基本配置
  5. data 后台拿到的数据 响应主体信息
  6. headers 响应头信息
  7. request 原生xhr实例
  8. status HTTP状态码
  9. statusText 状态描述
  10. */
  11. });

image.png
image.png

  1. //POST请求传参,基于DATA把信息通过请求主体传递给服务器(默认会把DATA中的内容转换为JSON格式的字符串传递给服务器,而不是JQ中看到的xxx=xxx&xxx=xxx)
  2. axios({
  3. method: 'post',
  4. url: '1.json',
  5. data: {
  6. name: 'xxx',
  7. }
  8. }).then(function(response){
  9. console.log(response);
  10. });


真实项目中我们使用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对象里

  1. axios.get("./1.json", {
  2. params: {
  3. ID: 12345
  4. }
  5. })
  6. .then(function (response) {
  7. console.log(response);
  8. })
  9. .catch(function (error) {
  10. console.log(error);
  11. });
  • 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);
});