axios和fetch


前面的vuex提到了異步請求,在vue里異步請求怎么請求呢,很顯然jq.ajax是不用了,不是不能用,而是沒必要,jq是操作dom的工具,強行用浪費功能,還會加大打包后的體積,而且是沒有promise的,所以有大佬封裝了新的ajax,名字叫axios,也是vue的作者尤雨溪推薦使用的,這個axios是可以直接在nodejs端使用的

自行百度安裝,axios是沒有封裝成可以讓vue.use()的這種使用模式的,也沒必要,但最好二次封裝下

二次封裝
先去創建一個util的工具文件夾,在里面再新建一個叫request.js文件,直接上代碼

// 引入axios
import axios from 'axios'
import store from 'store'

const service = axios.create({
  // url = base url + request url
  // 這是請求的前綴的三元運算符,是需要配合proxy使用的
  // process.env.NODE_ENV 是nodejs的全局變量,需要懂點nodejs才知道
  // 意思是如果是開發【development】環境
  // 前綴就是當前本地地址 "localhost:端口" + "/proxy" + "url值"
  // 如果不是開發環境,意思就是線上環境,即打包后上線的環境,你讓用戶請求 "localhost:3000" 肯定是請求不到的
  // 所以打包出來的就是 "http://xxx.com" + "url值"
  baseURL: process.env.NODE_ENV === 'development' ? '/proxy' : 'http://xxx.com', //process.env.VUE_APP_BASE_API
  // 最長等待時間
  timeout: 5000 // request timeout
})

// 請求前的操作,config參數是請求前的一切數據,可以打印查看
service.interceptors.request.use(
  config => {
    // 在這里可以做權限的判斷
    if(0){
        // 不同意請求 return 一個Promise.reject
        return Promise.reject("當前賬號無該請求權限")
    }
    // 從vuex里取token值,如果這么寫上面需要去引入vuex
    if (store.getters.token) {
      // 可以自動添加請求頭token,就不需要自己手動一次次去寫了
      // 什么是token,面試題篇里有
      config.headers['X-Token'] = getToken()
    }
    // 如果同意請求,需要return config
    return config
  },
  error => {
    // 錯誤處理
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// 請求后的操作,response是axios二次封裝的返回值
service.interceptors.response.use(
  response => {
    // 在返回值可以看到請求的地址
    const url = response.config.url;
    // 這是真正的返回數據
    const res = response.data;
    // 可以做一些統一的返回值處理
    if (res.code === 2000) {
      // 成功就返回res
      return res
    } else {
      return Promise.reject(new Error(res.msg || 'Error'))
    }
  },
  error => {
    // 無返回的錯誤處理
    return Promise.reject(error)
  }
)
// 這就是整個插件了
export default service

如何使用

寫好接口
建議是統一一個文件夾叫req或者叫api,然后根據模塊放置請求

image.png

// 引入封裝好的插件
import request from '@/utils/request'

export function getInfo(opt) {
  return request({
    // 這個在開發環境會變成 "http:localhost:端口" + "/proxy" + "/user/info"
    // 正式環境就是 "http:baidu.com" + "/user/info"
    url: '/user/info',  
    method: 'get',
    // get用params
    params: opt
  })
}

export function post(opt) {
  return request({
    url: '/post',  
    method: 'post',
    // post用data
    data: opt
  })
}

在vue文件里調用
在vuex使用查看上一篇,跟在vue文件里寫法一樣的

// 引入
import { getInfo,post} from 'api/user';

export default {
    data(){
        return { ... }
    },
    mounted(){
       getInfo({id:123123}).then(res=>{
          console.log(res)
       })
    },
}

// 因為是promise請求還可以用
Promise.all([getInfo(),post()])
// 或者async
async mounted(){
     var res = await getInfo({id:123123})
},

上傳文件

export function upload(formdata) {
  return request({
    url: '/uploadFile',
    method: 'post',
    data: formdata,
    headers: { 'Content-Type': 'multipart/form-data' },
  })
}

注意,axios的post請求是會自動轉成了json字符串【跟文件上傳無關】,如果后端說他不要json格式,一定要key-value的form表單格式,就不能用上面的封裝了,得安裝qs插件,還要修改headers

qs插件

import qs from 'qs';

export function upload(formdata) {
  return request({
    url: '/form',
    method: 'post',
    data: qs.stringify(data),
    headers: {'content-type': 'application/x-www-form-urlencoded'},
  })
}

就上面這么寫,是發不出去請求的

我們上面出現過的這兩句話

1. 這個在開發環境會變成 "http:localhost:端口" + "/proxy" + "/user/info"
2. 正式環境就是 "http:baidu.com" + "/user/info"

在jq-ajax請求的那一篇的最后面就寫過,請求需要滿足的條件

  1. 需要存在這個請求地址,第一個請求地址一看就沒有,腳手架里怎么會有這個接口呢
  2. 需要瀏覽器不跨域

如何滿足上面的兩個條件,查看下一篇

補充fetch
fetch並不是一個插件,是跟xhr一樣的,原生的,請求方式,目前兼容不好,普及不多,這里做個記錄

fetch('https://www.baidu.com/search/error.html', {
    method: 'POST',
    credentials: 'xxx' // 強制加入憑據頭
    headers: new Headers({
      'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式為表單提交
      'Accept': 'application/json' // 通過頭指定,獲取的數據類型是JSON
    }),
    body: new URLSearchParams([["foo", 1],["bar", 2]]).toString()
})
.then((res)=>{
    return res.text()
})
.then((res)=>{
    console.log(res)
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM