3--Axios和fetch

作者: Daeeman | 来源:发表于2020-07-09 16:44 被阅读0次

    Axios

    1. axios 简介

    axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:

    • 从浏览器中创建 XMLHttpRequest
    • 从 node.js 发出 http 请求
    • 支持 Promise API
    • 拦截请求和响应
    • 转换请求和响应数据
    • 取消请求
    • 自动转换JSON数据
    • 客户端支持防止 CSRF/XSRF

    2. axios安装和引入

    1. cmd安装(和cdn引入)
    使用npm
      npm install axios -S
    使用淘宝源
      cnpm install axios -S
    或者使用cdn:
      <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

    2. main.js

    import axios from 'axios';
    Vue.prototype.$http = axios;
    // 挂载axios到vue的原型公用方法上面
    // 所有vue的实例都将拥有$http
    

    3. method方法中使用

    methods: {
      postData () {
        this.$http({
          method: 'post',
          url: '/user',
          data: {
            name: 'xiaoming',
            info: '12'
          }
       })
    }
    

    3. 执行 GET 请求

    // 向具有指定ID的用户发出请求
    this.$http.get('/user?ID=12345')
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
    
    // 也可以通过 params 对象传递参数
    this.$http.get('/user', {
        params: {
          ID: 12345
        }
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
    
    完整案例(爱笑话)
    <template>
      <div class="about">     
        <van-pull-refresh v-model="isLoading" @refresh="getJoks(2)">//上拉刷新  
                 
        <div class="pannel" v-for="item in joks" :key="item.docid">
          <h3>{{item.title}}</h3>
          <p>{{item.summary}}</p>
        </div> 
        </van-pull-refresh>
            
        <div style="margin:15px;">//点击加载
            <van-button type="primary" block @click="getJoks(1)"> 加载更多</van-button>
        </div>   
      </div>
    </template>
    <style>
      .pannel{
        margin: 15px;
        box-shadow:0 3px 6px #eee;
        border-radius: 8px;
        overflow: hidden;    
      }
      .pannel h3{
        line-height: 44px;
        padding: 0 15px;
        font-size: 16px;
        font-weight: normal;
        background-color: #fafafa;
      }
      .pannel p{
        line-height: 1.8;
        color:#777;
        font-size: 14px;
        padding: 15px;
      }
    </style>
    <script>
    export default {
      data(){return {
        joks:[],
        page:1,
        isLoading:false,
        }},
      created(){
        this.getJoks();
      },
      methods:{
        getJoks(type=1){    
          if(type==2){
               this.isLoading = true; // 显示正在加载中
          }
          // url 固定的后端给的地址
          this.$http.get("http://www.520mg.com/mi/list.php?page="+this.page)
          .then(res=>{
            if(type==1){
                 this.joks = this.joks.concat(res.data.result.filter(item=>item.title));
            }else if(type==2){
                  this.joks =res.data.result.filter(item=>item.title).concat(this.joks);
            }    
            // .filter(item=>item.title); 过滤掉没有title数据
            // res是后端返回的数据
            // .data.result 返回的数据格式有个 data属性,data有result属性
            this.page++;
            this.isLoading = false; //停止加载
          })
          .catch(err=>{
            console.log(err);
          })
        }
      }
    }
    </script>
    

    4. 执行 POST 请求

    AxiosPostLogin2(value) {
          //  console.log("api =>" +api+" data"+data)
            return new Promise((resolve, reject)=>{
              console.log(value)
              axios.post("http://assetsx-api-ingress.prd.10.42.226.2.k8sprd-wks.k8s.wistron.com/getNWEquipsByCondition", value,{headers: { 'Content-Type': 'application/json; charset=utf-8' }}).then((res)=>{
                console.log("返回的结果是:"+JSON.stringify(res))
                resolve(res.data)
              })
            })
      } 
    
    

    c

    this.$http.post( 
        url,
        "k1=v1&k2=v2",// 参数 
        {headers:{'Content-Type':'application/x-www-form-urlencoded'}}
        // 设置url编码格式
    )
    .then(res>{}) // 成功
    .catch(err=>{}) // 失败
    
    
    完整案例(电影票房数据)
    <template>
      <div class="about">
        <h3 v-for="(item,index) in movies" :key="index">
           {{item.MovieName}}  --票房:{{item.amount}}万
        </h3>
        <input type="file" ref="file"> <button @click="upImg">上传</button>
        <img :src="pic" v-if="pic" width="200" alt=""> 
      </div>
    </template>
    <style></style>
    <script>
    export default {
      data(){return {
        movies:[],
        pic:'',
        }},
      created(){
        this.getMovies();
      },
      methods:{
        upImg(){
          let file  = this.$refs.file.files[0];
          let data = new FormData();
          data.append('file',file);
          let configs = {
            headers:{'Content-Type':'multipart/form-data'}
          }
          this.$http({
            method:'post',
            url:'/ajax/file.php',
            data,
            configs
          })
          .then(res=>{
            console.log(res);
            if(res.data.error==0){
              this.pic = 'http://www.520mg.com'+res.data.pic;
              // 设置图片的路径
              this.$refs.file.value='';
              // 清空files文件
            }
          })
          .catch(err=>console.log(err))
        },
    //**********************************************************************
        getMovies(){
          this.$http.post(
            "http://www.endata.com.cn/API/GetData.ashx",
            "MethodName=BoxOffice_GetPcHomeList",
            // {headers:{"Content-Type":"application/x-www-form-urlencoded"}}
            )
            .then(res=>{
              console.log(res.data);
              this.movies = res.data.Data.Table1.sort((a,b)=>{return a.amount>b.amount?-1:1});
            })
            .catch(err=>{
              console.log(err);
            })
        },
    </script>
    
    

    5. 执行 多个 请求

    function getUserAccount() {
      return $http.get('/user/12345');
    }
    function getUserPermissions() {
      return $http.get('/user/12345/permissions');
    }
    axios.all([getUserAccount(), getUserPermissions()])
      .then($http.spread(function (acct, perms) {
        //两个请求现已完成
      }));
    

    6. 文件上传

    let data = new FormData();     // 创建表单数据
    data.append('file',file);      //  插入表单数据
    let configs = {headers:{'Content-Type':'multipart/form-data'} };
    this.$http({
           method:'post', //请求方法
           url:"/ajax/file.php",// 请求地址
           data,              // 请求数据      
           configs,               // 请求配置 
         })
    .then(res>{}) // 成功
    .catch(err=>{}) // 失败
    
    完整案例之文件上传
    <template>
      <div class="about">
        <input type="file" ref="file"> <button @click="upImg">上传</button>
        <img :src="pic" v-if="pic" width="200" alt=""> 
      </div>
    </template>
    <style></style>
    <script>
    export default {
      data(){return {
        pic:'',
        }},
      methods:{
        upImg(){
          let file  = this.$refs.file.files[0];
          let data = new FormData();
          data.append('file',file);
          let configs = {
            headers:{'Content-Type':'multipart/form-data'}
          }
          this.$http({
            method:'post',
            url:'/ajax/file.php',
            //url:'http://www.520mg.com/ajax/file.php',
            data,
            configs
          })
          .then(res=>{
            console.log(res);
            if(res.data.error==0){
              this.pic = 'http://www.520mg.com'+res.data.pic;
              // 设置图片的路径
              this.$refs.file.value='';
              // 清空files文件
            }
          })
          .catch(err=>console.log(err))
        },
    </script>
    
    

    7.全局配置

    在 main.js中进行配置,(要写在axios挂载之前)

    1. 可以删除页面中 http://520mg.com
    axios.defaults.baseURL = "http://520mg.com"
    // 配置基础url
    
    1. 可以删除页面中 :{headers:{"Content-Type":"application/x-www-form-urlencoded"}}
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    // 配置post编码
    // 配置完成可以去掉页面中的post头信息(header)
    
    1. 全局配置
    axios.defaults.withCredentials = true;
    //跨域请求的全局凭证
    

    8. axios本地json数据获取

    1. 把json拷贝到public 目录
    2. 发起ajax请求
    this.$http.get('/js/youdata.json' )
          .then(res>{}) // 成功
          .catch(err=>{}) // 失败
    
    import jsonp from 'jsonp';
                jsonp(url,opts,function(err,data){                
                    console.log("json方法",data);                
                })
        },
    opts:{prefix: '__jp',param:'callback'}
    
    完整案例之肺炎数据获取
    <template>
      <div class="about">
        <h1>{{add}}</h1>
        <h3 v-for="(item,index) in feiyan" :key="index">
            {{item.one_level_area}}
            {{item.sure_cnt}}
        </h3>   
      </div>
    </template>
    <style></style>
    <script>
    import jsonp from '../assets/js/jsonp'
    export default {
      data(){return {
        add:'',//地址
        feiyan:'',//新冠肺炎国外数据  
        }},
      created(){
        this.getAdd();
        // 获取ip对应的地址  
        this.getFeiyan();
        // 获取肺炎数据
      },
      methods:{
        getFeiyan(){
            this.$http.get("http://localhost:8080/feiyan/special?uc_param_str=pccplomi&feiyan=1&district=1&tabStart=0&tabEnd=1&tabBrief=1&aid=3804775841868884355")
            // this.$http.get("http://localhost:8080/special.json")
            // 本地数据存储在 /pubic/special.json
            .then(res=>{
              // console.log(res.data);
              this.feiyan = res.data.data.feiyan.cities
              .filter(item=>item.country!="中国") 
              .sort((a,b) => a.sure_cnt>b.sure_cnt?-1:1) ;
              // 过滤掉所有中国的数据
              // 数据按确诊数从大到小排序         
            })
            .catch(err=>{
              console.log("err",err);
            })
        },
        getAdd(){
          jsonp("http://api.map.baidu.com/location/ip?ak=I5p02PxH5e459CAk9vt4elbXNTkgfxde",{},
          (err,data)=>{
            this.add = data.content.address;
          }
          )
        },  
    </script>
    

    扩展 fetch

    MDN传送门

    fetch('http://example.com/movies.json')
        .then(function(response) {
            return response.json();
        })
        .then(function(data) {
            console.log(data);
        })
        .catch(function(e) {
            console.log("Oops, error");
        });
    

    ES6箭头函数

    fetch(url)
        .then(response=> response.json())
        .then(data=> console.log(data))
        .catch(e=> console.log("Oops, error", e))
    

    使用 async/await 来做最终优化:

    (async function(){
        try {
            let response = await fetch(url);
            let data = response.json();
            console.log(data);
        } catch(e) {
            console.log("Oops, error", e);
        }
    })();
    

    使用 await 后,写异步代码就像写同步代码一样爽。await 后面可以跟 Promise 对象,表示等待 Promise resolve() 才会继续向下执行,如果 Promise 被 reject() 或抛出异常则会被外面的 try…catch 捕获。
    http://hjingren.cn/2017/05/09/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0-es6Async%E5%87%BD%E6%95%B0/

    GET请求

    fetch(url, {
        method: "GET", //默认
        headers:{
            "Accept": "application/json, text/plain, */*"
        }
    })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(e => console.log("Oops, error", e))
    

    POST请求

    fetch(url, {
        method: "POST",
        headers: {
            "Accept": "application/json, text/plain, */*",
            "Content-type":"application:/x-www-form-urlencoded; charset=UTF-8"
        },
        body: "name=hzzly&age=22"
    })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(e => console.log("Oops, error", e))
    

    使用Fetch请求发送凭证

    要使用Fetch发送带有诸如cookie之类的凭证的请求。你可以在选项对象中将credentials属性值设置为“include”:

    fetch(url,{
        credentials: "include"
    })
    

    封装POST请求

    //将对象拼接成 name=hzzly&age=22 的字符串形式
    function params(obj) {
        let result = ''
        for(let item in obj) {
            result += `&${item}=${obj[item]}`
        }
        if(result) {
            result = result.slice(1)
        }
        return result
    }
    
    function post(url, paramsObj) {
        let result = fetch(url, {
            methods: 'POST',
            credentials: "include"
            headers: {
                "Accept": "application/json, text/plain, */*",
                "Content-type":"application:/x-www-form-urlencoded; charset=UTF-8"
            },
            body: params(paramsObj)
        })
        return result
    }
    
    let obj = {
        name: 'hzzly',
        age: 22
    }
    post(url, obj)
        .then(response => response.json())
        .then(data => console.log(data))
        .catch(e => console.log("Oops, error", e))
    
    

    相关文章

      网友评论

        本文标题:3--Axios和fetch

        本文链接:https://www.haomeiwen.com/subject/wmjscktx.html