在vue-cli@3.X中配置代理解决开发环境的跨域问题
我们在前后端分离开发时,不得不面对跨域问题,对于跨域,可以在前端这样处理配置.
1、在 vue.config.js文件中配置 proxy
属性,将 API 请求代理到 API 服务器上,设置 devServer.proxy
vue.config.js文件中配置 proxy
属性,将 API 请求代理到 API 服务器上,设置 devServer.proxy
例如:
App.vue
<template> <div id="app"> <!-- <div id="nav"> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </div> --> <!-- 遍历数组 item:数组元素 index:元素对应下标--> <div v-for="(item,index) in data.data1" :key="'0' + index"> {{item}} {{index}} </div> <!-- 遍历对象 item:对象值 key:对象键 index:对象值对应下标--> <!-- <div v-for="(item, key, index) in data.data1[0]" :key="index"> {{key}} {{item}} {{index}} </div> --> <div v-text="data.word"></div> <div v-html="data.words"></div> <button @click='handleClick'>开始请求数据</button> <!-- <router-view/> --> </div> </template> <script> export default { name:"App", data() { return{ data:{ data1:[ {a:1,b:2}, {c:3,d:4}, {e:5,f:6}, ], word:"<h1>hello</h1>", words:"<h1>hellos</h1>" } } }, mounted(){ }, methods:{ handleClick:function(){ console.log(this.data); this.axios .get("/api/user")//此处为/api开头的请求地址,后面可以被node代理服务器识别到并加以代理成同源的域名 .then(res => { console.log('成功了',res); // this.data.data1=res.data.data4 this.$set(this.data.data1,0,res.data.data4[0]) }) .catch(res => { console.log('失败了',res) console.log(res) }) } } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } #nav { padding: 30px; } #nav a { font-weight: bold; color: #2c3e50; } #nav a.router-link-exact-active { color: #42b983; } </style>
vue.config.js
module.exports = { /* 部署生产环境和开发环境下的URL:可对当前环境进行区分,baseUrl 从 Vue CLI 3.3 起已弃用,要使用publicPath */ /* baseUrl: process.env.NODE_ENV === 'production' ? './' : '/' */ publicPath: process.env.NODE_ENV === 'production' ? './' : './', /* 输出文件目录:在npm run build时,生成文件的目录名称 */ outputDir: 'dist', /* 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录 */ assetsDir: "assets", /* 是否在构建生产包时生成 sourceMap 文件,false将提高构建速度 */ productionSourceMap: false, /* 默认情况下,生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存,你可以通过将这个选项设为 false 来关闭文件名哈希。(false的时候就是让原来的文件名不改变) */ filenameHashing: false, /* 代码保存时进行eslint检测 */ lintOnSave: true, /* webpack-dev-server 相关配置 */ devServer: { /* 自动打开浏览器 */ open: true, /* 设置为0.0.0.0则所有的地址均能访问 */ host: 'localhost', port: 8081, https: false, hotOnly: false, /* 使用代理解决跨域问题(跨域的常用方式:1、在前端解决跨域问题 2、后端直接设置访问控制允许源Access-Control-Allow-Origin:* 代表允许全部域名跨域,也可单独设置指定域名跨域 3、后端配置Nginx反向代理) */ proxy: { /* 详解: 1、proxy 里面的'/api'什么意思? 答:作用是是告诉node, 我的接口要是以'/api'开头的才用代理.例如:App.vue中的请求接口地址 "/api/user" 符合以/api开口的条件,所以会被代理, 最后代理的路径 由http://localhost:8081/api/user ==》变成 http://10.10.38.94:3000/api/user 虽然浏览器的Network的Headers/General URL还是http://localhost:8081/api/user,但实际上在请求后,被node代理服务器悄悄代理成了http://10.10.38.94:3000/api/user再去请求真实后代接口地址 2、pathRewrite里面的‘^/api’:'' 什么意思? 答:由上面可知,代理成了http://10.10.38.94:3000/api/user,但是我们实际的真实后台接口地址是http://10.10.38.94:3000/user,所以在请求前一刻,需要将/api去除(把/api给重写成空字符串了)。 '^/api'是一个正则表达式,表示要匹配请求的url中,全部http://localhost:8081/api/user 转接为 http://10.10.38.94:3000/user */ '/api': { /* 目标代理服务器地址 */ target: 'http://10.10.38.94:3000/', /* 允许跨域 */ changeOrigin: true, pathRewrite: { '^/api' : '' } }, }, }, }
前端部分到此已经解决跨域问题了,需要注意的是修改了vue.config.js文件必须要运行yarn server重启项目才能生效!!
2、下面我们来搭建一个简单的node后台接口提供数据服务
一:搭建服务端
1、在项目中新建一个名为server的文件夹,并在文件夹中新建index.js(用于搭建服务端)和user.js(用于存放返回给客户端的json数据)
index.js文件代码
// 主要分四步:
// 引入-cors解决跨域-引入并发送数据-设置监听端口
var express = require("express"); //首先引入express模块,不了解去看nodejs教程 安装:npm install express
var app = express();
var fs = require("fs"); // 文件系统,用于引入user.json的数据 也可以自己随便写个数据 ;
var cors = require("cors");// 这个比较重要,解决跨域问题.npm install cors 装一下
//在node后台使用cors设置origin,当时返回给浏览器一个访问控制允许源Access-Control-Allow-Origin:*字段,也可以实现跨域,不过有些浏览器不支持
//因为此次我们测试的是在vue-cli@3.X中配置代理解决开发环境的跨域问题,所以先关闭此处的cors跨域配置
// app.use(cors({
// origin: "*",//允许全部域名跨域(全局跨域)
// // origin: ['http://localhost:8080','http://127.0.0.1:8066'], // 这是本地的默认地址和端口,vue启动的项目就是在这里,此处填写允许跨域的地址,这样保证了等会我们在浏览器能访问服务器的数据(user.json)
// methods: ["GET", "POST"],
// alloweHeaders: ["Content-Type", "Authorization"]
// }))
// 获取请求地址中的/user并匹配,可以添加多个
app.get("/user", function (req, res) { //"/user" 是自定义的,用于显示在地址栏
// 数据来源:
//方法一:从文件中获取数据
//读取储存数据的文件
fs.readFile(__dirname + "/" + "user.json", "utf-8", function (err, data) { // __dirname是文件夹的名,我们用fs读取user.json
// 把读取的文件通过 res.end()发送回给客户端
res.send(data)
})
//方法二:在本文件临时定义数据
// var response ={
// "data1": {
// "name": "Mr.李",
// "age": "24",
// "look": "very handsome",
// "girlfriend":"保密"
// },
// "data2": {
// "name": "Mr.王",
// "age": "25",
// "look": "very handsome",
// "girlfriend":"保密"
// }
// }
// res.send(response)
});
// 监听请求地址的对应端口
var server = app.listen(3000, function () { // 设置服务端端口为3000,即:http://127.0.0.1:3000
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
})
注意的是修改了index.js文件必须要运行node index.js重启node服务器或者清楚浏览器缓存才能生效!!
user.json文件代码
{
"data1": {
"name": "Mr.李",
"age": "24",
"look": "very handsome",
"girlfriend":"保密",
"id":"1",
"data1-1":{
"pid":"1.1"
}
},
"data2": {
"name": "Mr.王",
"age": "25",
"look": "very handsome",
"girlfriend":"保密",
"id":"2",
"data2-1":{
"pid":"2.1"
}
},
"data3": {
"name": "Mr.王",
"age": "25",
"look": "very handsome",
"girlfriend":"保密",
"id":"2",
"data2-1":{
"pid":"2.1"
}
},
"data4":[
{"aa":1,"bb":2},
{"cc":3,"dd":4},
{"ee":5,"ff":6}
]
}
2、进入index.js目录下执行node index.js命令启动服务器
*开启成功如上图
3、最后,我们可以在浏览器上试试效果了
![](https://img2020.cnblogs.com/blog/1551162/202007/1551162-20200701150152482-200012052.png)
经测试,可以看到在浏览器控制台已经成功打印出了请求到的数据!!