必背-6.axios和fetch用法

文章目录

必背-6.axios和fetch用法

axios

1.axios是什么?

  • axios官方网址:http://www.axios-js.com/zh-cn/docs/
  • axios是什么:axios是基于Promise封装的ajax库,基于这个类库发送ajax请求,默认就是基于promise管理的,核心是XMLHttpRequest
  • ==axios基于请求方式分为了:get/head/delete/opations/post/put/patch==方法。

2.axios中GET系列的使用方法?

  • 首先需要导入axios对应插件:

    • npm i axios
      <script src="node_modules/axios/dist/axios.min.js"></script>
      
  • get方法的创建:axios.get([url],[config]);对应的delete/head/opations方法都是用下面规范

    • [url]:放我们请求资源的对应接口路径,不带参数

      • "http://127.0.0.1:8080/user/list"
        
    • [config]:用来配置请求信息,是一个对象类型,每个属性按照键值对的形式配置,常用8个

      • 我们配置的这些属性实际上是在给这次请求的xhr实例设置私有属性,不要以为都是在给请求头设字段。
      • baseUrl:[string]:配置请求地址的前缀
      • params:[string/object]:属性值可以是字符串可以是对象
        • 对象:会将里面属性名和属性值拼接为键值对,问号拼接到URL后面
        • 字符串:无论字符串内写的是xxx,那直接在URL后面拼接为**“0=xxx”**
      • headers:[object]:属性值是对象类型,作用同ajax中的xhr.setRequestHeader()
        • headers:{"Content-Type":application/json}:但是在get跟Post中,Content-Type属性一般不需要咱们手动改
        • headers:{"Name":"sjh"}:可以通过headers给请头添加我们想传的数据
      • timeout:[number]:请求超时时间,数字类型但为是ms
      • withCredentials:[boolean]:默认为false,true:表示允许跨域携带资源凭证,false:表示不允许
      • responseType:[string]:把服务器返回的结果转为对应的数据格式,默认是json(服务器返回的结果,我们都把它转为json对象),还有其他类型:‘arraybuffer/blob/document/json/text/strem’;
      • onUploadProgress:[function]:监听文件上传进度
      • validateStatus:[function]:里面是一个函数,函数中的return可以配置status决定状态值在什么范围才算请求成功,默认2xx为请求成功

3.axios中POST系列的使用方法?

  • 首先需要导入axios对应插件:

    • npm i axios
      <script src="node_modules/axios/dist/axios.min.js"></script>
      
  • axios中post的创建方式axios.post([url],[data],[config]);对应的put/patch方法

    • url:字符串类型,请求的目标路径
    • [data]:可以是字符串类型,可以对象类型,post中请求体的信息,如同xhr.send(),中传的数据,但一般不会传字符串。
    • [config]:**对象类型,**配置请求的配置项
  • post常配置的配置项

    • 与get相同,但是没有params,因为post不同请求头传参
    • transformRequest:function([data],[headers]){return xxx}:POST请求专用的方法,对请求主体进行格式处理
      • [data]获取的是axios.post()方法中的第二个参数的值,data必须是标准普通对象,我们在内部就可以给他做格式的处理,return什么,[data]请求体就会变成什么
      • 比如我们的[data]传的是JSON对象格式的,但后台想要urlencoded格式的,那我们就可以用transformRequest转换一下。
  • axios中POST请求的请求主体:

    • data就是请求体信息:发送之前,会在内部默认处理称为JSON字符串,再传给服务器
      • 如果服务器想要的不是JSON字符串,可以将[data]值设置为服务器想要的字符串。
      • 如果服务器想要的是urlencoded字符串,我们有两种方式做处理:
        • 方式一:【引入Qs库】,基于Qs.stringify/parse做处理:axios.post([url],Qs.stringify(data),[config]);
          • Qs.stringify(data):将对象转为urlencoded字符串
          • Qs.parse(data):将urlencoded字符串转为对象
        • 方式二:使用transformRequest:function ([data],[heders]){return xxx} 的方式,自行改成想要的格式。

4.axios内部做的优化?

  • axios内部做了一个非常有用的事情:根据我们传递给服务器的内容格式,自动帮我们设置请求头中的 Content-Type ,让其和传递的格式相匹配「MIME类型」
    • urlencoded格式字符串 : Content-Type:‘application/x-www-form-urlencoded’
    • json格式字符串 :Content-Type:‘application/json’
    • FormData格式对象: Content-Type:‘multipart/form-data’

5.对象分为几大类?

  • 对象类型「引用数据类型」
    • 标准普通对象 object
    • 标准特殊对象 Array、RegExp、Date、Math、Error……
    • 非标准特殊对象 Number、String、Boolean……
    • 可调用/执行对象「函数」function

6.axios做get请求时存在的三种错误情况?

  • 有响应体:返回的错误对象中有状态码:response->status,没有code
  • 无响应体
    • timeout:请求超时或被中断,没有状态码,有code属性:code:"ECONNABORTED" response:undefined
    • navigator.onLine=false(断网)时:没有状态码,也没有code和response,只能用navigator.onLine=false判断。

7.axios的get和post请求另一种写法?

axios({
        method: 'get',
        url:'http://127.0.0.1:9999/user/list',
        params:{id:1},//重点,get方法中用params
        headers:{}
    }).then(res=>{
        console.log(res);
})

axios({
        method: 'post',
        url:'http://127.0.0.1:9999/user/list',
        data:{id:1},//重点,post方法中才能有data
        headers:{}
    }).then(res=>{
        console.log(res);
})

8.axios二次封装?

  • 提取公共配置:axios的二次封装就是将所有请求的公共部分提取到一个默认的js文件中,所有的请求都会遵循这个默认配置文件。

    • 默认配置:axios.defaults.xxx;->xxx:是能够配置的配置项,如timeout

      • axios.defaults.baseURL = 'http://127.0.0.1:9999';//设置公共 前缀路径
        
        axios.defaults.transformRequest = data => {//设置公共 转换请求体格式
            if (isPlainObject(data)) return Qs.stringify(data);
            return data;
        };
        axios.defaults.timeout = 60000;//设置公共 请求超时时间
        
    • 请求/响应拦截器:axios.interceptors.request/response

  • 单独配置:单独写的请求配置,优先级高于公共配置

9.axios的请求、响应拦截器怎么使用?

  • 基于拦截器进行公共部分提取

  • 请求拦截器:发生在 “配置项准备完毕” 和 “发送请求” 之间

  • 响应拦截器:发生在 “服务器返回结果” 和 “业务代码自己处理 .then” 之间

  • //请求拦截
    axios.interceptors.request.use(config => {
    					// config对象包含的就是准备好的配置项,最后返回啥配置,就按照这些配置发请求
      return config;
    });
    
  • //响应拦截:如果成功就将结果返回给用户,如果失败,进行处理再返回
    axios.interceptors.response.use(response => {
        // 请求成功:把响应主体信息返回给业务层去使用
        return response.data;
    }, reason => {
        // 请求失败:根据不同的失败原因做不同的提示
        if (reason && reason.response) {
            // @1 有返回结果,只不过状态码不对
            let {status} = reason.response;
            switch (+status) {//switch是做===比较
                case 403:
                    alert('服务器不爱搭理你~~');
                    break;
                case 404:
                    alert('你傻啊,地址都错了~~');
                    break;
                case 500:
                    alert('服务器开小差了~~');
                    break;
            }
        } else {
            // @2 请求超时或者中断 
            if (reason && reason.code === "ECONNABORTED") {
                alert('请求超时或者被中断了~~');
            }
            // @3 断网
            if (!navigator.onLine) {
                alert('当前网络出问题了~~');
            }
        }
        // 统一失败提示处理完,到业务代码处,我们还是要失败的状态,这样才能继续做一些自己单独想做的失败处理
        return Promise.reject(reason);
    });
    
    

Fetch

1.Fetch的使用?

  • ES6新增的一种API Fetch,是浏览器原生自带的,核心不是XMLHttpRequest,是基于全新的通信机制实现的[本身是基于promise管理的]

  • 用法:

    •     fetch('http://localhost:9999/job/list',{
              method:'GET',
              headers:{},//请求头信息
              //必须是字符串
              // body:JSON.stringify({id:0})//请求体中的参数,GET/HEAD/OPtions/DELETE方法没有请求体,不能有body
          }).then(function(response){
              console.log(response);//获取的是一个响应信息的对象,看不到真正的响应体
              return response.json(); //想要获取响应体的信息,需要调用对应格式的response.xxx()方法
      
          }).then(function(value){
              console.log(value);
          })
      
  • 注意点:

    • GET/DELETE/OPTIONS/HEAD方法中不能存在body。
    • fetch得到的结果是一个Promise对象,可以调用then方法PromiseResult是响应的信息,但找不到响应体信息。
    • 想要获取响应体信息需要调用result对应数据格式的方法,比如想获取json格式的响应数据:result.json()/result.text()/result.formdata()/…
    • result.json等格式获取方法只能使用一次,且只能有一种

2.axios和Fetch的区别?

  • 相同点:他俩都是发送请求的
  • 实现原理不同:axios是基于promise封装的ajax类库,fetch是ES6中浏览器原生的API
  • 传参字段不同:
    • axios的get请求参数放到params中,post请求体信息放到data
    • fetch的get请求参数直接跟在url后面,post请求体信息放在body
  • 环境支持程度:node环境中不支持fetch,需要引入node-fetch文件才能支持
  • 功能差异:axios中的配置和拦截器等功能,fetch中都没有。

同源与跨域

1.如何区分是同源还是跨域?

  • 浏览器默认存在的浏览器同源策略:不允许不同源获取数据。
  • ==同源:==请求的url路径与请求端协议类型、域名、端口号,完全相同,则表示同源
  • ==跨域:==只要协议类型、域名、端口号其中一个不一样就称为跨域

2.跨域请求在项目中的场景和意义,以及解决跨域的方案?

  • 跨域请求不被允许的原因:【跨域请求就是做通行证】服务器不允许发送请求的地址访问**(origin 源地址)**,Access-Control-Allow-Origin

  • 情景一:开发时候是跨域的,项目在部署上线后是同源的【现在很少了】

    • 解决方案:开发时的跨域:修改服务器本地的hosts文件即可,【修改服务器本地DNS缓存】【很少用】
  • 情景二:开发和部署的时候都是跨域的:比如将一个项目文件按类型分服务器部署

    • 方案一:JSONP跨域请求方案【缺点:只支持Get请求】
    • 方案二:CROS跨域资源共享【由服务器去配置】
    • 方案三:PROXY跨域资源代理【最常用,需要前端去配置的
    • 方案四:postMessage+iframe【已经淘汰了】

3.CROS资源跨域共享如何设置跨域请求?

  • 设置允许源 Access-Control-Allow-Origin:

    • 	res.header('Access-Control-Allow-Origin', 'http://127.0.0.1:5500');
      	res.header("Access-Control-Allow-Credentials", true);
      
  • *:允许所有源访问,但是由于服务器认为这样不安全,所以不允许外界携带跨域资源凭证访问(如cookie

  • “http://127.0.0.1:8080”:指定单一源访问,允许携带

上一篇:axios 的基本使用


下一篇:读书有感-《创业公司走向移动化的5个误区》