zoukankan      html  css  js  c++  java
  • Vue--封装axios、跨域

    封装axios

    因为项目中很多组件中要通过Axios发送异步请求,所以封装一个Axios对象。自己封装的Axios在后续可以使用axios中提供的拦截器。

    在src下创建一个utils目录,在utils目录下创建一个request.js文件

    在public下创建一个db.json文件,写点数据,用来我们测试

    之前我们使用axios发送请求的时候是使用的下面的方式

    [
        {
            "name":"张三",
            "age":17
        },
        {
            "name":"李四",
            "age":52
        },
        {
            "name":"王五",
            "age":37
        }
    ]
    db.json
    import axios from 'axios'
    
    axios.get('./db.json').then(response =>{
        console.log(response.data)
    })

    在components下的HelloWorld.vue中引用测试一下

    在浏览器 的控制台就可以看到db.json里的数据,这种方法是我们之前的方法,现在我们要封装。

    修改request.js文件

    import axios from 'axios'
    
    
    const request = axios.create({
        baseURL: '/',     //基础路径,根据不同环境设置 baseURL, 最终发送请求时的URL为: baseURL + 发送请求时写URL ,
        timeout: 5000     //超时时间,5000毫秒
    })
    
    export default request  // 导出自定义的axios对象

    我们自己封装好了axios,那怎么测试知道我们封装的有没有问题,我们来进行测试

    在src目录下创建一个api目录,在下面创建一个test.js文件

    在test.js文件里写入如下代码

    // @就是src目录的路径
    import request from '@/utils/request'
    
    
    // 下面的这种是使用最原始的方式来发送get请求
    // request.get('/db.json').then(response =>{
    //     console.log(response.data)
    // })
    
    
    // 以对象配置的方式进行指定请求方式
    // request({
    //     method: 'get',
    //     url: '/db.json'
    // }).then(response =>{
    //     console.log('对象方式', response.data)
    // })
    
    export default {
        getList(){
            const res = request({
                method: 'get',
                url: '/db.json'
            })
            return res
        }
    }

    在HelloWorld.vue的script标签里写如下代码

    <script>
    // 导入接口
    import testApi from '@/api/test'
    export default{
      data(){
        return{
          list: {}
        }
      },
      created(){  // 调用method里的fetchData方法
        this.fetchData()
      },
      methods: {
        fetchData(){
          testApi.getList().then(response =>{
            console.log('get3',response.data)
            this.list = response.data // 给data里的list重新赋值
          })
        }
      }
    }
    
    // export default {
    //   name: "HelloWorld",
    //   props: {
    //     msg: String
    //   }
    // };
    </script>

    属性浏览器,控制台里可以看到db.json里的数据,则我们的配置是没有问题的。

    跨域

    前后端分离时,前端和后端API服务器可能不在同一台主机上,就存在跨域问题,浏览器限制了跨域访问。

    同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域。

    如下面示例存在跨域:

    前端页面部署在:http://localhost:8001 即本地ip端口8001上;

    后端API部署在: http://localhost:8002 即本地ip端口8002上 ;

    它们IP一样,但是端口不一样,所以存在跨域问题。

    演示跨域:

    1.将 zz-mmsdb.json 拷贝到 axios-demopublic 目录下,axios-demo 工程就是 复制了zz-mms 重命名了

    2.axios-demovue-config.js 更改 端口号, 将端口号更改为 8001

    3. 启动 axios-demo

    npm run serve

    启动后,查看控制台显示的访问地址,我的是 http://localhost:8001/

    4. 查询是否可以直接访问到数据, 访问 http://localhost:8001/db.json

    5. 修改 zz-mmssrcapi est.js , 发送请求给 8001 接口,修改下  BASE_URL 值

    const BASE_URL = 'http://localhost:8001' 

    6. 重新刷新 页面, 查看控制台报错, 出现跨域问题.

    跨域解决:

    通过代理请求的方式解决,将 API 请求通过代理服务器请求到 API 服务器。

    开发环境中,在 vue.config.js 文件中使用 devServer.proxy 选项进行代理配置。

    参考:https://cli.vuejs.org/zh/config/#devserver

    解决开发环境跨域问题

    在  vue.config.js 文件中使用  devServer.proxy 选项进行代理配置

    module.exports = {
        devServer: {
            port: 8888, // 端口号,如果端口被占用,会自动加1
            host: "localhost",  // 主机名,127.0.0.1  真机 0.0.0.0
            https: false,  // 协议
            open: true,  // 启动服务时自动打开浏览器访问
            proxy: {  // 开发环境代理配置
                'dev-api':{  // 匹配 /dev-api 开头的请求,
                    // 目标服务器地址,代理访问http://localhost:8001
                    target: 'http://localhost:8001',
                    changeOrigin: true,  // 开启代理服务器
                    pathRewrite:{
                        //  会将 /dev-api 替换为 '',也就是 /dev-api 会移除,
                        // 如 /dev-api/db.json 代理到 https://localhost:8080/db.json
                        '^dev-api': ''
                    }
                }
            }
    
        },
        lintOnSave: false,  // 关闭格式检查
        productionSourceMap: false // 打包时不会生成.map文件,加快打包速度
    }
    vue.config.js

     将 test.js 中的 修改如下:

    // @就是src目录的路径
    import request from '@/utils/request'
    
    
    const BASE_URL = '/dev-api'
    
    export default {
        getList(){
            const res = request({
                method: 'get',
                url: BASE_URL + '/db.json'
            })
            return res
        }
    }

    重启项目,防止不生效

     配置不同环境 常量值

    参考:https://cli.vuejs.org/zh/guide/mode-and-env.html

    开发环境请求 Mock.js 获取数据,开发环境请求后台接口获取数据,不同环境请求的URL不一样,所以要为不同环境匹配不同请求接口URL,通过路径前缀进行匹配。当前只针对开发环境,后面会生产部署再讲生产如何实现。

    1. 在 zz-mms 根目录下创建 .env.development 和 .env.production 文件,

    .env.development 文件配置(注意开发和生产环境配置不要搞反了)

    VUE_APP_SERVICE_URL 值可更改为你自已配置的 Easy-Mock 接口服务地址

    # 使用 VUE_APP_ 开头的变量会被 webpack 自动加载,process.env.VUE_APP_xxx
    
    # 开发环境的前缀
    VUE_APP_BASE_API = '/dev-api'
    
    # 目标服务接口地址,是按照自己的环境来的,添加或更改服务后,需要重启服务
    VUE_APP_SERVICE_URL = 'http://localhost:8001'

    测试:在 main.js 中添加以下代码,看下浏览器控制台是否会输出

    在项目任意模块文件中,都可以使用 process.env.VUE_APP_BASE_API 获取值

    console.log(process.env.VUE_APP_BASE_API)
    重构代理配置

    在重构 vue.config.js 中的  devServer.proxy 代理配置

    module.exports = {
        devServer: {
            port: 8888, // 端口号,如果端口被占用,会自动加1
            host: "localhost",  // 主机名,127.0.0.1  真机 0.0.0.0
            https: false,  // 协议
            open: true,  // 启动服务时自动打开浏览器访问
            proxy: {  // 开发环境代理配置

    [process.env.VUE_APP_BASE_API]:{ // 自动获取,注意要[],在.env.development里配置的 // 目标服务器地址,在.env.development里配置的。代理访问http://localhost:8001 target: process.env.VUE_APP_SERVICE_URL, changeOrigin: true, // 开启代理服务器 pathRewrite:{ ['^' + process.env.VUE_APP_BASE_API]: '' // 自动获取 } } } }, lintOnSave: false, // 关闭格式检查 productionSourceMap: false // 打包时不会生成.map文件,加快打包速度 }

    修改  utils/request.js 文件配置:  baseURL: process.env.VUE_APP_BASE_API

    import axios from 'axios'
    
    
    
    const request = axios.create({
        baseURL: process.env.VUE_APP_BASE_API, //基础路径,.env.development
        timeout: 5000 //超时时间,5000毫秒
    })
    
    // request.get('./db.json').then(response =>{ // 使用request。而不是使用axios
    //     console.log(response.data)
    // })
    export default request  // 导出自定义的axios对象

    去掉 test.js 中的  BASE_URL 

    // @就是src目录的路径
    import request from '@/utils/request'
    
    
    
    export default {
        getList(){
            const res = request({
                method: 'get',
                url: '/db.json'
            })
            return res
        }
    }

    重启项目,再次访问

  • 相关阅读:
    VMware克隆虚拟机
    3种Redis分布式锁的对比
    高并发下缓存与数据库双写不一致解决方案
    30分钟Maven入门到精通
    Linux安装rabbitmq (解决guest无法登陆问题)
    RocketMQ高性能原理(pushConsumer,CommitLog,ZeroCopy)
    XA 分布式事务原理(转)
    SpringBoot学习(八)RestTemplate/WebClient 调用REST服务、Validation校验和发邮件
    @Valid和@Validated的总结区分(转)
    Dubbo 同步调用原理(转)
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11740345.html
Copyright © 2011-2022 走看看