我們在前后端分離開發時,不得不面對跨域問題,對於跨域,可以在前端這樣處理配置.
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、最后,我們可以在瀏覽器上試試效果了

經測試,可以看到在瀏覽器控制台已經成功打印出了請求到的數據!!