当前位置:   article > 正文

数据交互系列:简述vue项目中的两种请求方式(axios和vueResource)

数据交互系列:简述vue项目中的两种请求方式(axios和vueResource)

今天学习了vue的两种发送请求的方式,vueResource和axios,比较了两种方式的使用

VueResource模块发送请求

1. VueResource概述
  • VueJS的生态圈除了VueRouter之外,还有很多的插件,在网络请求中,vue是借助于vue-resource模块来进行异步请求,跨域请求。
  • vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应。也就是说,$.ajax能做的事情,vue-resource插件一样也能做到,而且vue-resource的API更为简洁。
  • 特点
    • 体积小,vue-resource非常小巧,在压缩以后只有大约12KB,服务器启用gzip压缩后只有4.5KB大小。
    • 支持主流的浏览器,和vuejs一样,vue-resource除了不支持IE9以下的浏览器,其他主流的浏览器都支持。
    • 支持PromiseAPI和URI Templates,Promise是es6的特性,Promise的中文含义为"先知",Promise对象用于异步计算。URl Templates表示URI模块,有些类似于ASP.NET MVC的路由模块。
    • 支持拦截器
      拦截器是全局的,拦截器可以在请求发送前和发送请求后做一些处理。
      拦截器在一些场景上非常有用,比如请求发送前在headers中设置access_token,或者在请求失败时,提供共通的处理方式。
2. VueResource的使用步骤
  • 使用步骤

  • cdn 下载网址
    https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js

  • 安装vue-resource

  npm install --save vue-resource
  • 1
  • 引入vue-resource模块
  import VueResource from 'vue-resource'
  Vue.use(VueResource)
  • 1
  • 2
  • 调用模块中$http发起请求
   this.$http.get('url')
   .then(function(response){
        ....
   })
  • 1
  • 2
  • 3
  • 4
  • 在组件实例加载完之后,会自动调用vueResource这个模块
<script>
    Vue.use(vueResource)
    new Vue({
        el:'#app',
        mounted(){
            this.$http.get('http://localhost:5050/index')
            .then(result=>{
                console.log(result.data)
            })  //发送get请求
           
            this.$http.get('http://localhost:5050/details',{
                params:{lid:5}
            }).then(result=>{
                console.log(result.data)
            }) //发送带数值的get请求
            
            this.$http.post('http://localhost:5050/users/signin',{
                uname:"dingding",
                upwd:'123456'
            }).then(result=>{
                console.log(result.data)
            })//发送post请求
        }
        
    })
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

axios方式发送请求

1. axios概述
  • 从vue2.0开始已经在推崇用新的方法(axios)来代替vue-resource
  • Axios跟vue无关,在任何平台都可以发送请求,比如nodejs 网页等
  • 所以从新版的vue开始,vue-resource已经不再被使用
2. axios的使用步骤
  • cli中axios的使用
// main.js
import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
注册方式1:Vue.use(VueAxios,axios)
注册方式2:Vue.prototype.axios=axios


//使用
this.axios.get('demo/getTest?user=tom')
  .then((res)=>{
      console.log(res.data)
  })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • html中axios的使用
<head>
     <script src="js/axios.min.js"></script>
     <script src="js/vue.min.js"></script>
</head>
<body>
    <div id="app">
        axios.default.baseURL="http://localhost:5050"
        Vue.prototype.axios=axios
        new Vue({
            el:'#app',
            mounted(){
                this.axios.get('/index').then(result=>{
                    console.log(result.data)
                })
            }
        })
    </div>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
3. Ajax应该在哪个生命周期
  • 有两个选择 created 和 mounted
  • 推荐 mounted
原因
created阶段钩子函数已经可以去读取数据,mounted阶段钩子函数组件已经渲染完成,由于ajax请求是异步,当获取到数据时,从beforeCreate到mounted已经运行完了,所以在created和mounted发送请求都可以。
  • 1
模拟操作
@/utils/data.js
function getData(){
	return new Promise((resolve)=>{
		setTimeout(()=>{
			resolve(1000)
		},2000)
	})
}
export default getData
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
// home.vue

<div> {{count}} </div>
import getData from  ../utils/data
export default{
	async created(){
	    let result=await getData()
		this.count=result
	},
	mounted(){
		console.log('mounted')
	},
	activated(){
		console.log('activated')
	},
	deactivated(){
		console.log('deactivated')
	},
	updated(){
		console.log(this.data)
	}, 
	//组件渲染完,状态发生改变才会打印
	//控制台的update有打印,说明在mounted和created中发送请求获取数据是在组件渲染之后,并且再一次更新dom树。这也说明后台获取的数据无法做一次渲染
	data(){
		return{
			count:100
		}
	}
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
4. 实际项目中封装axios实例和请求方法的思路
  1. 在utils公共方法文件夹的request.js中
// 导入axios
import axios from 'axios'
// 创建axios实例
const service = axios.create({
  // 公共接口--这里注意后面会讲
  baseURL: process.env.BASE_API,
  //   baseURL: '/api',
  // 超时时间 单位是ms,这里设置了3s的超时时间
  timeout: 10 * 1000
})

// 设置请求和响应的拦截器
service.interceptors.request.use(config => {},error=>{})
service.interceptors.response.use(response => {},error=>{})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  1. 在utils公共方法文件夹的http.js中导入axios实例
// 导入封装好的axios实例
// 封装 get put delete post请求方法
import request from './request'
const http = {
  /**
   * methods: 请求
   * @param url 请求地址
   * @param params 请求参数
   */
  get (url, params) {
    const config = {
      method: 'get',
      url: url
    }
    if (params) config.params = params
    return request(config)
  },
  getData (url, data) {
    const config = {
      method: 'get',
      url: url
    }
    if (data) config.data = data
    return request(config)
  },
  post (url, params) {
    const config = {
      method: 'post',
      url: url
    }
    if (params) config.data = params
    return request(config)
  },
  put (url, params) {
    const config = {
      method: 'put',
      url: url
    }
    if (params) config.params = params
    return request(config)
  },
  delete (url, params) {
    const config = {
      method: 'delete',
      url: url
    }
    if (params) config.params = params
    return request(config)
  }
}
export default http
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  1. 在api文件夹的api.js中写接口
import request from '@/utils/request'
import http from '@/utils/http'

// 两种方式写接口
// 举例
// 登录接口
export function login (data) {
  return request({
    url: 'api/logn',
    method: 'post',
    data: data,
  })
}

// 首次任务开启接口
export function startJob (id) {
  return request({
    url: 'api/jb/strt?factoryId='+id,
    method: 'get'
  })
}

// 同步任务接口
export function manualStartJob (param) {
  return http.post('api/job/StartJob', param)
}

...

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  1. 在组件中xxx.vue 使用封装好的接口方法
import {login,startJob,manualStartJob} from './api/api'
  • 1

vue项目中解决跨域问题

  • 跨域的原因:浏览器同源策略
同源策略

著名的安全策略,注意:同源策略不是服务器行为,而是浏览器行为。 在这里插入图片描述

前端跨域报错:

在这里插入图片描述

服务端解决跨域问题
  • 上线需要使用nginx代理或者服务器配置cors(每中语言有自己得配置方式)
  • 以nodejs的express框架为例:
npm i cors

let express=require('express')
let cors=requrie('cors')
let app=express()
app.listen(3000,()=>{
    console.log('3000端口,已启动') 
})

// 配置跨域
app.use(cors,{
    //允许跨域的服务器地址,可以写多个
    origin:['http://127.0.0.1:8080','http://localhost:8080']
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
vue项目实现跨域的原理

跨域是浏览器得安全策略,服务器和服务器之间发送请求没有跨域,在启动脚手架时会启动一个内置得web服务器,在请求时浏览器并没有直接和需要请求得服务器通信,而是通过内置得web服务器中转。

注意:项目上线需要把打包后得文件放在服务器运行,而不是启动脚手架运行,所以没有内置服务器中转请求,此方式只适用于开发阶段。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ooWbZ0TL-1683602902114)(https://note.youdao.com/yws/res/21666/WEBRESOURCE6ba5b29fcadfc7a73bef6dce6bae9ad2)]

@vue/cli4.5中处理
  • 一般情况下如果需要使用低版本得脚手架,需要重新安装脚手架
  • 当然,npx 可以临时创建一个目录,使用4.5的脚手架
npx @vue/cli@4.5 create vue2
  • 1
  • 需要手动创建一个vue.config.js
modules.export={
    devServer:{
        // 配置代理服务器
        proxy:{
            //定义处理那种请求的开头
            //以后只要以/demo为开头的请求,都会被处理
            '/demo'{
                // 往哪个服务器里发送请求
                target:'http://127.0.0.1:3000',
                pathRewrite:{
                    // ^代表字符串开头,实际发送请求时把/demo替换成''
                    // 因为/demo并不是请求的一部分,只是代理的标识
                    '^/demo':''
                }
            }
        }
        
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
@vue/cli5.0中处理
在vue脚手架中 5.0之后的版本会默认有vue.config.js文件,解决跨域问题需要在该文件中配置代理服务器
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: truedevServer:{
       //配置代理服务器
       proxy:{
            //定义处理那种请求的开头
            //以后只有是以/demo为开头的请求,都会被处理
           '/demo':{
                //往哪个服务器发送请求
                target:’http://127.0.0.1:3000,
                PathRewrite:{
                     //^代表字符串开头,实际请求时把/demo替换成‘‘
                     // 因为/demo并不是请求得一部分,只是代理的标识
                    '^/demo':''
                }
            }
        }
    }
})    
配置完后重启脚手架生效…….
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

拦截器

VueRource 使用拦截器

在这里插入图片描述

//cli
Vue.prototype.http=vueRource
Vue.http.interceptors.push((req,next)=>{
    //请求发送前的处理逻辑
    next((res)=>{
        //请求发送后的处理逻辑
        //res参数会返回给successCallback
        //或 errorCallback
        return res
    })
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
//cdn
<div id="app"></div>
<script>
    Vue.use(vueResource)
    Vue.$http.interceptors.push((req,next)=>{
        console.log('发送请求前拦截')
        console.log(req)
        next((res)=>{
            console.log('收到响应结果后拦截')
            console.log(res)
        })
    })
    new Vue({
        el:'#app'
        data:{
            ...
        },
        methods:{
           ...  
        },
        ...
    })
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
axios 使用拦截器

axios.interceptors.response.use
在这里插入图片描述

import axios from 'axios'
var axios=axios.create() // 创建一个实例
axios.interceptors.request.use(config=>{ //请求拦截器
    console.log('在发送请求前拦截...')
    console.log(config)
    return config       
})
axios.interceptors.response.use(
  res=>{  //响应拦截器
      console.log(`在收到响应后拦截...`)
      console.log(res)
      return res
  }
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 案例
/** **   request.js   ****/
// 导入axios
import axios from 'axios'
import { message } from 'ant-design-vue'
// 1. 创建新的axios实例,
const service = axios.create({
  // 公共接口--这里注意后面会讲
  baseURL: process.env.BASE_API,
  //   baseURL: '/api',
  // 超时时间 单位是ms,这里设置了3s的超时时间
  timeout: 10 * 1000
})
// 2.请求拦截器
service.interceptors.request.use(config => {
  // 发请求前做的一些处理,数据转化,配置请求头,设置token,设置loading等,根据需求去添加
  //   config.data = JSON.stringify(config.data) // 数据转化,也可以使用qs转换
  //   config.data = config.data
  config.headers = {
     // 'Content-Type': 'application/x-www-form-urlencoded' // 配置请求头
  }
  // 注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookie
  // 这里取token之前,你肯定需要先拿到token,存一下
  if (sessionStorage.getItem('session')) {
    // config.headers['authorization'] = sessionStorage.getItem('session')
  }
  // config.withCredentials = true
  return config
}, error => {
  Promise.reject(error)
})

// 3.响应拦截器
service.interceptors.response.use(response => {
  // 接收到响应数据并成功后的一些共有的处理,关闭loading等
  if (response.data.code === 10000) {
    message.error('用户信息过期,请重新登录')
    window.localStorage.removeItem('sync-session')
    window.sessionStorage.removeItem('sync-session')
    location.href = ('/sync/#/')
  }
  return response
}, error => {
  /** *** 接收到异常响应的处理开始 *****/
  if (error && error.response) {
    // 1.公共错误处理
    // 2.根据响应码具体处理
    switch (error.response.status) {
      case 400:
        error.message = '错误请求'
        break
      case 401:
        error.message = '未授权,请重新登录'
        break
      case 403:
        error.message = '拒绝访问'
        break
      case 404:
        error.message = '请求错误,未找到该资源'
        // window.location.href = '/NotFound'
        break
      case 405:
        error.message = '请求方法未允许'
        break
      case 408:
        error.message = '请求超时'
        break
      case 500:
        error.message = '服务器端出错'
        break
      case 501:
        error.message = '网络未实现'
        break
      case 502:
        error.message = '网络错误'
        break
      case 503:
        error.message = '服务不可用'
        break
      case 504:
        error.message = '网络超时'
        break
      case 505:
        error.message = 'http版本不支持该请求'
        break
      default:
        error.message = `连接错误${error.response.status}`
    }
  } else {
    // 超时处理
    if (JSON.stringify(error).includes('timeout')) {
      message.error('服务器响应超时,请刷新当前页')
    }
    error.message = '连接服务器失败'
  }

  message.error(error.message)
  /** *** 处理结束 *****/
  // 如果不需要错误处理,以上的处理过程都可省略
  return Promise.resolve(error.response)
})
// 4.导入文件
export default service

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/466021
推荐阅读
相关标签
  

闽ICP备14008679号