vue項目配置代理如何解決跨域問題
Vue項目配置代理
前端向服務器發(fā)送請求時,經(jīng)常會遇到跨域問題,那么什么是前端跨域呢?
在vue項目中如何利用代理解決呢?
1. 這里以axios發(fā)請求為例
axios.get("/abc/def"); axios.get("/abc/ghi"); axios.post("/abc/jkm");
axios發(fā)送的請求是本地的服務器地址拼接上發(fā)送的請求,如 http://localhost:8080/abc/def
2. 如果發(fā)送的請求都以 /abc 開頭
那么我們就可以在proxy中進行服務器代理配置。
devServer: { ? ? proxy: { ? ? ? "/abc": { ? ? ? ? target: "http://XX.XX.XX.XX:8081", ? ? ? ? changeOrigin: true, ? ? ? ? ws: true, ? ? ? ? secure: false, ? ? ? }, ? ? }, },
"/abc":{} : 引號中代表監(jiān)測的是以 /abc 開頭的接口
target : 代表監(jiān)測到以 /abc 開頭的接口后,把axios請求中前面的本地服務器地址改為后端接口地址,實際發(fā)送給后端的請求就是下方后一個請求
http://localhost:8080/abc/def --> http://XX.XX.XX.XX:8081/abc/def
changeOrigin
: 是否跨域ws
: 如果要代理 websockets,配置這個參數(shù)secure
: 如果是https接口,需要配置這個參數(shù)(如果是http接口,也可以不寫這個參數(shù))pathRewrite
:替換請求中匹配的內容。在3的方法2中詳細解釋用法,上方未使用此參數(shù)
3. 代理多個接口
http://localhost:8080/zzz/one
http://localhost:8080/xxx/two
方法1:監(jiān)測多個接口,可以在proxy中寫多個配置:(適用于target不同的代理,相同也可以用這個方法,就是會麻煩一點,對于相同的target方法2會比較方便)
devServer: { ? ? proxy: { ? ? ? ? "/zzz": { ? ? ? ? ? target: "http://XX.XX.XX.XX:8082", ? ? ? ? ? changeOrigin: true, ? ? ? ? ? ws: true, ? ? ? ? }, ? ? ? ? "/xxx": { ? ? ? ? ? target: "http://XX.XX.XX.XX:8083", ? ? ? ? ? changeOrigin: true, ? ? ? ? ? ws: true, ? ? ? ? }, ? ? }, },
那么實際發(fā)送給后端的請求就是:
http://XX.XX.XX.XX:8082/zzz/one
http://XX.XX.XX.XX:8083/xxx/two
方法2:使用axios進行前設置(適用于target相同的代理)
// 一般在全局設置里引入,例如main.js,方便第二行的配置被每一個axios請求識別 import axios from "axios"; // 只要發(fā)送axios請求,就在請求前加入/api的開頭,例如 /zzz/one -> /api/zzz/one axios.defaults.baseURL = "/api"; ? ?
進行了上方的配置后,在本地發(fā)送的請求會變?yōu)?/p>
http://localhost:8080/api/zzz/one
http://localhost:8080/api/xxx/two
而后可以設置只監(jiān)聽 "/api" 的代理,不過要設置pathRewrite參數(shù):
devServer: { ? ? proxy: { ? ? ? ? "/api": { ? ? ? ? ? ? target: "http://XX.XX.XX.XX:8084", ? ? ? ? ? ? changeOrigin: true, ? ? ? ? ? ? ws: true, ? ? ? ? ? ? pathRewrite: { ? ? ? ? ? ? ? "^/api": "", ? ? ? ? ? ? }, ? ? ? ? }, ? ? }, },
pathRewrite :檢查代理的請求中是否有 /api ,有的話把 /api 替換為冒號后面的內容,案例為替換成空字符串,也就是刪去 /api 。(^是正則表達式的內容,意思是限定開頭)
- 本地請求 http://localhost:8080/api/zzz/one ->
- 代理后請求 http://XX.XX.XX.XX:8084/api/zzz/one ->
- 設置pathRewrite后的請求 http://XX.XX.XX.XX:8084/zzz/one
- 所以代理完成后真正發(fā)送給后端的請求就是 http://XX.XX.XX.XX:8084/zzz/one 啦。
1.統(tǒng)一給請求添加/api方便監(jiān)測代理 2.統(tǒng)一刪去/api發(fā)送正確的請求)
- 注意:小伙伴們可能會看到瀏覽器中右鍵檢查打開的控制臺中,網(wǎng)絡->標頭->常規(guī),中的請求網(wǎng)址顯示的還是 http://XX.XX.XX.XX:8084/api/zzz/one 。
- 這是因為瀏覽器的同源策略,經(jīng)過代理設置的請求發(fā)送給后端已經(jīng)變成 http://XX.XX.XX.XX:8084/zzz/one 沒有/api 的形式了,不用被瀏覽器顯示的請求網(wǎng)址干擾。
- 如果實在不想看到瀏覽器的請求網(wǎng)址中有api,可以采用方法1。
什么是跨域?
JavaScript同源策略:當協(xié)議、子域名、主域名、端口號中任意一個不相同時,都算作不同域。
不同域之間相互請求資源,就算作“跨域”。
同源策略要求源相同才能正常進行通信,即協(xié)議、域名、端口號都完全一致。**同源策略限制:**表單提交、AJAX請求等。
注意:跨域并不是請求發(fā)不出去,請求能發(fā)出去,服務端能收到請求并正常返回結果,只是結果被瀏覽器攔截了。
proxy代理解決跨域
**原理:**瀏覽器是禁止跨域的,但是服務端不禁止,在本地運行npm run serve等命令時實際上是用node運行了一個服務器,因此proxyTable實際上是將請求發(fā)給自己的服務器,再由服務器轉發(fā)給后臺服務器,做了一層代理,因此不會出現(xiàn)跨域問題。
當我們在用本機去找服務器要數(shù)據(jù)時會產生跨域問題,所以利用vue-cli去開啟一個代理服務器。
配置(vue.config.js)
方法一
優(yōu)點:配置簡單、請求資源時直接發(fā)給前端(8080)即可
缺點:不能配置多個代理,不能靈活的控制請求是否走代理
當請求了前端不存在的資源時,該請求會轉發(fā)給服務器(優(yōu)先匹配前端資源)
?module.exports = { ? ? ?devServer: { ? ? ? ? ? ? ?proxy: 'http://localhost:5000', ? ? ?} ?}
方法二
優(yōu)點:可以配置多個代理,且可以靈活的控制請求是否走請求
缺點:配置繁瑣,請求資源時必須加前綴
//開啟代理服務器(方法二) ? ? devServer: { ? ? ? ? proxy: { ? ? ? ? ? ? // ?'/yu'為請求前綴,用于控制是不是走代理,想走代理時就在請求前綴前邊加上這個請求前綴 ? ? ? ? ? ? '/yu': { ? ? ? ? ? ? ? ? target: 'http://localhost:5000', ? ? ? ? ? ? ? ? pathRewrite: { "^/yu": "" }, //重寫路徑 ?匹配以/yu為開頭的路徑都變?yōu)榭兆址? ? ? ? ? ? ? ? ? ws: true, //用于支持websocket ? ? ? ? ? ? ? ? changeOrigin: true //用于控制請求頭中的host值 ? ? ? ? ? ? }, ? ? ? ? ? ? '/demo': { ? ? ? ? ? ? ? ? target: 'http://localhost:5001', ? ? ? ? ? ? ? ? pathRewrite: { "^/demo": "" }, ? ? ? ? ? ? ? ? ws: true, //用于支持websocket ? ? ? ? ? ? ? ? changeOrigin: true //用于控制請求頭中的host值 ? ? ? ? ? ? }, ? ? ? ? } ? ? }
請求時:
請求前綴必須跟著端口號
getStudents() { ? ? ? axios.get("http://localhost:8081/yu/students").then( ? ? ? ? (response) => { ? ? ? ? ? console.log("請求成功了", response.data); ? ? ? ? }, ? ? ? ? (error) => { ? ? ? ? ? console.log("請求失敗了", error.message); ? ? ? ? } ? ? ? ); ? ? }, ? ? getCars() { ? ? ? axios.get("http://localhost:8081/demo/cars").then( ? ? ? ? (response) => { ? ? ? ? ? console.log("請求成功了", response.data); ? ? ? ? }, ? ? ? ? (error) => { ? ? ? ? ? console.log("請求失敗了", error.message); ? ? ? ? } ? ? ? ); ? ? },
1.vue-cli 2 是在路徑為config/index.js的文件下proxyTable里配置的,該文件是整個項目的主要配置入口
// node自帶路徑工具. var path = require('path') // 分為兩種環(huán)境,dev和production module.exports = { ? dev: { ? ? // 配置好后一定要關閉原來的server,重新npm run dev啟動項目。不然無效。 ? ? proxyTable: { ? // 需要代理的接口,可以跨域 ? ? ? // 用‘/api'開頭,代理所有請求到目標服務器 ? ? ? '/api': { ? ? ? ? ? ? target: 'http:xxx.com', // 目標接口域名 ? ? ? ? ? ? changeOrigin: true, // 是否啟用跨域 ? ? ? ? ? ? pathRewrite: { //這里要理解成用'/api'代替target里面的地址,后面的組件中我們調用接口的時候直接用api代替,比如我要調用'http://40.00.100:3002/user/add',直接寫成'/api/user/add'即可 ? ? ? ? ? ? ? '^/api': '' ?// 即/api相當于http://40.00.100:3002 ? ? ? ? ? ? } ? ? ? ? } ? ? ?} ? } }
注意:‘/api’ 為匹配項,因為在 ajax 的 url 中加了前綴 ‘/api’,而原本的接口是沒有這個前綴的,所以需要通過 pathRewrite 來重寫地址,將前綴 ‘/api’ 轉為 ‘/’。
如果本身的接口地址就有 ‘/api’ 這種通用前綴,就可以把 pathRewrite 刪掉。
2.vue-cli 3 是自己在根目錄下新建vue.config.js文件,在devServer.proxy對象里配置(當然也有其他方式),配置后會和隱藏的配置自動進行整合
module.exports = { ? ? // cli3 代理是從指定的target后面開始匹配的,不是任意位置;配置pathRewrite可以做替換 ? ? devServer: { ? ? ? proxy: { ? ? ? ? '/yourapi': { ? //代理api,/yourapi的意義在于,聲明axios中url已/api開頭的請求都適用于該規(guī)則,注意是以/yourapi開頭,即:axios.post({url: '/yourapi/xxx/xxx'}) ? ? ? ? ? target: 'yourserver', ? //服務器真實api地址,即需要請求的目標接口,此處target的意義在于:造成跨域是因為訪問的host與我們的請求頭里的origin不一致,所以我們要設置成一致,這個具體請看下文 ? ? ? ? ? changeOrigin: true, ? ?//是否跨域,true為開啟代理:在本地會創(chuàng)建一個虛擬服務端,然后發(fā)送請求的數(shù)據(jù),并同時接收請求的數(shù)據(jù),這樣服務端和服務端進行數(shù)據(jù)的交互就不會有跨域問題 ? ? ? ? ? ws: true, // 是否啟用websockets,根據(jù)實際情況看是否需要配置該項 ? ? ? ? ? pathRewrite: {? ? ? ? ? ? ? ? ?'^/yourapi': 'https://我是服務器/api' ? //重寫路徑 ? ? ? ? // 此處是大部分文章都不會明說的的地方, ? ? ? ? // 既然我們設置了代理,則所有請求url都已寫成/yourapi/xxx/xxx,那請求如何知道我們到底請求的是哪個服務器的數(shù)據(jù)呢 ? ? ? ? // 因此這里的意義在于, 以 /yourapi開頭的url請求,代理都會知道實際上應該請求那里, ? ? ? ? // ‘我是服務器/yourapi',后面的/api根據(jù)實際請求地址決定,即我的請求url:/yourapi/test/test,被代理后請求的則是 ? ? ? ? // https://我是服務器/yourapi/test/test ? ? ? ? ? }? ? ? ? ? } ? ? ? } ? ? } ? }
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
vue中el-table兩個表尾合計行聯(lián)動同步滾動條實例代碼
項目開發(fā)中遇到一個比較兩個form差異的需求,但當item過多就需要滾動條,下面這篇文章主要給大家介紹了關于vue中el-table兩個表尾合計行聯(lián)動同步滾動條的相關資料,需要的朋友可以參考下2022-05-05vue3?+?element-plus?的?upload?+?axios?+?django?實現(xiàn)文件上
這篇文章主要介紹了vue3?+?element-plus?的?upload?+?axios?+?django?文件上傳并保存,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01vue-router 按需加載 component: () => import() 報錯的解決
這篇文章主要介紹了vue-router 按需加載 component: () => import() 報錯的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09Element-UI中<el-cascader?/>回顯失敗問題的完美解決
我們在使用el-cascader控件往數(shù)據(jù)庫保存的都是最后一級的數(shù)據(jù),那如果再次編輯此條數(shù)據(jù)時,直接給el-cascader傳入最后一級的數(shù)據(jù),它是不會自動勾選的,下面這篇文章主要給大家介紹了關于Element-UI中<el-cascader?/>回顯失敗問題的完美解決辦法,需要的朋友可以參考下2023-01-01vuex實現(xiàn)數(shù)據(jù)持久化的兩種方案
這兩天在做vue項目存儲個人信息的時候,遇到了頁面刷新后個人信息數(shù)據(jù)丟失的問題,在查閱資料后,我得出兩種解決數(shù)據(jù)丟失,使用數(shù)據(jù)持久化的方法,感興趣的小伙伴跟著小編一起來看看吧2023-08-08淺談Vue.js應用的四種AJAX請求數(shù)據(jù)模式
本篇文章主要介紹了淺談Vue.js應用的四種AJAX請求數(shù)據(jù)模式,本文將詳細介紹在Vue應用程序中實現(xiàn)AJAX的四個方法,有興趣的可以了解一下2017-08-08