在vue-cli@3.X中配置代理解决开发环境的跨域问题

我们在前后端分离开发时,不得不面对跨域问题,对于跨域,可以在前端这样处理配置.

1、在 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://www.cnblogs.com/itgezhu/p/13219326.html