Vue笔记-Vue-cli 创建的项目使用服务器代理跨域详解?

1,776 阅读5分钟

前言

写项目,跨域永远是个绕不开的问题,除非自己在localhost上玩.以前总是后端用cors的方式去解决这个问题.老问题,后端如果没整,怎么玩?写vue项目,常用vue-cli工具依照webpack模板去搭一个项目结构.每个人都知道用npm run dev 启动项目,但是更应该知道的是我们是依赖了webpack-dev-server代理服务器(用node.js写的)才启动了这个项目.没亲手设置可不代表不存在.所以才会在vue项目中有服务器代理这种配置项.补一句:二手资料害死人.

问题描述:

使用 Vue-cli 创建的项目,(前端)开发地址是 localhost:8080,需要访问 (后端)上的接口并不是这个,例如后端地址是http://192.168.199.168:8080/ ,数据访问是要跨域的哟!

抄来的方案:(先说说网上抄来抄去的一个手法)

1.在 config文件夹下index.js文件 的 dev 中添加配置项 proxyTable

  dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
    // 我们家的接口就不用api这种前缀,要怎样
      '/api': {
        target: 'http://192.168.199.168:8080/',
        changeOrigin: true,
        // 为什么不能说说pathRewrite到底是干什么的呢
        // 就知道要'^/api': '/'或者'^/api': '/'
        // 以及'/'''有什么区别
        // 哎,二手资料害死人
        pathRewrite: {
          '^/api': '/'
        }
      }
    },

2.使用axios插件时,发的请求

 axios.get('/api/yyd-manage/department/list')
.then(res => {
  console.log(res)
})
.catch(err => {
  console.log(err)
})

注:

1.使用了 axios,可以全局配置一个 baseURL,这样就不用挨个儿修改 url 了,可以省掉请求时的'/api',如:axios.get('/yyd-manage/department/list').

axios.defaults.baseURL = '/api'
//放在main.js文件中或者自己写一个js插件文件,在main.js中注册一下

这种手法可去你的吧,这属于强行操作

2.其中 '/api' 为匹配项,target 为被请求的地址

3.因为在 ajax 的 url 中加了前缀 '/api',而原本的接口是没有这个前缀的 所以需要通过 pathRewrite 来重写地址,将前缀 '/api' 转为 '/' 如果本身的接口地址就有 '/api' 这种通用前缀,就可以把 pathRewrite 删掉

上述操作全属于无脑抄袭,也就能骗骗我这种水货,完全不具备实用性

解决方案:

先看后端node服务器的一段简易代码

/*
	express框架是nodeJS的第三方模块 express框架实际上是对http模块的高度封装
*/
// 相当于引入了http模块
const express = require('express');
// 创建web服务器
const app = express();
// 当客户端以get方式请求/的时候
app.get('/index', (req, res) => {
	// express提供给我们的用来做响应的方法
	res.send('首页')
})

app.get('/list', (req, res) => {
	res.send('列表页')
})

app.get('/article', (req, res) => {
	res.send('文章页')
})

app.post('/getUserInfo', (rep, res) => {
	res.send('用户详情');
})

// 监听端口
app.listen(3000, () => {
	console.log('服务器启动成功');
});

例:其中的一个接口地址为:http://localhost:3000/index

vue-cli搭的webpack项目模板中前端设置服务器代理的代码

//在 config文件夹下index.js文件 的 dev 中添加配置项 proxyTable
  dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
      '/index': {
        target: 'http://localhost:3000/',
        changeOrigin: true,
        // 就不写pathRewrite
      }
    },

axios的get别名请求方法代码

//随便找个组件写个点击事件,发请求
  axios.get('/index')
    .then(res => {
      console.log(res);
    })
    .catch(err => {
       console.log(err); 
    })

返回内容(跨域成功)

并没有什么api,也没有pathRewrite: {"^/api" : ""}照样能使用

注:

1.proxyTable中的'/index'相当于一个标识,告诉webpack-dev-server,我的请求接口中以/index开头的地址要使用代理.不然的话, 可能你的 html, css, js这些静态资源都跑去代理. 所以我们只要接口用代理, 静态文件用本地.极端情况下你使用'/',那么所有的请求都会被代理,当然也可以正常跨域.

2.使用这种服务器代理的方式跨域时,不需要再去设置axios的基地址了,会报错. 即不用axios.get('http://localhost:3000/index')也不用axios.defaults.baseURL = 'http://localhost:3000/' 然后axios.get('/index')

3.proxyTable的配置项是webpack模板作者自己定义的,实际上真正生效的是webpack的devServer.proxy配置项,在build文件夹下webpack.dev.conf.js可以看到proxy: config.dev.proxyTable,靠这行代码实现的真正配置.iview-admin模板的vue.config.js中正是直接使用devServer.proxy而不是proxyTable,才让我在两个项目模板上困惑不已.

参考文章:vue-cli的webpack相关内容

参考文章:webpack的DevServer

4.pathRewrite的作用:

pathRewrite相当于一个重定向或者叫重写请求路径的作用,当然也可以移除,添加.

这是隶属于插件http-proxy-middleware的东西,该插件功能强大,还有路由等功能.

参考内容:http-proxy-middleware

上一段配置代码(修改配置项要注意重启项目)

  dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
      '/index': {
        target: 'http://localhost:3000/',
        changeOrigin: true,
        pathRewrite: {
            // 符号^是正则表达式符号,是匹配输入字符串的开始位置
            '^/index': '/list'
        }
      }
    },

本来我们要请求http://localhost:3000/index的接口现在就成了请求http://localhost:3000/list

axios的get别名请求方法代码

//随便找个组件写个点击事件,发请求
  axios.get('/index')
    .then(res => {
      console.log(res);
    })
    .catch(err => {
       console.log(err); 
    })

返回结果(是接口/list的结果,而不是/index的)

项目中的配置文件还是应当好好研究一下,不仅仅是跨域问题,还有开发模式,测试模式,生产模式,process.env等环境变量,路还很远.明年就要正式更新vue3.0了,变化真快.

推荐文章:vue-cli脚手架build目录中的webpack.dev.conf.js配置文件