使用proxytable 配置解決 vue-cli 的跨域請求問題【推薦】
本文適用人群:
- 會使用 vue-cli 搭建一個(gè)基本的 vue webpack 項(xiàng)目,本文的目錄結(jié)構(gòu)基于 webpack 模板結(jié)構(gòu)
- 懂得 axios 基本用法
問題導(dǎo)向
日常開發(fā)中,前端經(jīng)常需要通過 ajax 從后端獲取數(shù)據(jù)。而在這種前后端分離的開發(fā)模式下,往往前端項(xiàng)目與后端項(xiàng)目的 IP地址、端口號、協(xié)議 大概率是不一樣的,由于瀏覽器的安全策略設(shè)定,不進(jìn)行相應(yīng)配置的話,前端的請求就會被瀏覽器攔截掉啦。
假設(shè)某個(gè)頁面組件在加載的時(shí)候會向后端發(fā)送一個(gè)請求,然后根據(jù)返回的結(jié)果來渲染頁面。代碼示例如下:
前端項(xiàng)目通過 npm run dev
運(yùn)行在 localhost:8081 上,
后端項(xiàng)目通過 apache 運(yùn)行在 localhost/test/public/api/books
上
<template> <div class="hello"> <ul> <li v-for="book of books">{{book.name}}</li> </ul> </div> </template> <script> import axios from 'axios'; export default { name: 'HelloWorld', data() { return { books: [] } }, created(){ let self = this; axios.get("http://localhost/test/public/api/books") .then((response)=>{ self.books = response.data; }); } } </script>
直接訪問后端鏈接,將能得到以下返回內(nèi)容:
[ {"name":"javascript \u4ece\u5165\u95e8\u5230\u653e\u5f03"}, {"name":"\u9888\u690e\u75c5\u5eb7\u590d\u6307\u5357"}, {"name":"\u89c6\u529b\u4fdd\u62a4\u6307\u5357"} ]
但是當(dāng)我們在瀏覽器中運(yùn)行前端頁面,會報(bào)錯(cuò)!控制臺打印如下:
可見,瀏覽器對于跨域訪問進(jìn)行了限制,因?yàn)樵诶又星岸隧?xiàng)目url與后端項(xiàng)目url的端口號不相同,所以瀏覽器攔截了我們的請求。
解決方案
解決方式有很多種,包括可以很簡單粗暴地讓后端代碼設(shè)置一個(gè) Access-Control-Allow-Origin 頭來解決這個(gè)問題。但是,在實(shí)際開發(fā)中,后端的小哥哥們才不會理會你這個(gè)羞恥的小請求呢~
那怎么辦咧~
其實(shí)我們可以通過配置 vue 項(xiàng)目中的 config/index.js 來解決問題。
將 dev 中的 proxyTable 改為如下:
proxyTable: { '/api': { target: 'http://localhost/test/public/api/', changeOrigin: true, pathRewrite: { '^/api': '' } } },
接著,再將 vue 組件頁面中的 ajax 請求代碼改為如下:
// 改為這樣,原來是這樣:axios.get("http://localhost/test/public/api/books") axios.get("/api/books")
重新運(yùn)行 npm run dev ,運(yùn)行效果如下:
當(dāng)當(dāng)當(dāng)!成功!
為什么這么做?
當(dāng)我們打開瀏覽器的開發(fā)者工具查看一下網(wǎng)絡(luò)請求就會發(fā)現(xiàn),這個(gè) ajax 請求竟然是向我們前端的 webpack-dev-server 發(fā)送的:
而且居然能返回正確的數(shù)據(jù)???
瀏覽器有安全策略限制,但是第三方的服務(wù)(服務(wù)器)沒有呀,所以我們可以通過讓瀏覽器訪問前端開發(fā)服務(wù)器的url,讓前端開發(fā)服務(wù)器去向后端服務(wù)器發(fā)送請求,再返回?cái)?shù)據(jù)給瀏覽器,這樣子就不存在跨域問題啦。
當(dāng)我們在配置中這么寫時(shí):
proxyTable: { '/api': { target: 'http://localhost/test/public/api/', } },
對于8081端口的開發(fā)服務(wù)器而言,所有以 /api 開頭的 uri 都會被轉(zhuǎn)發(fā)到 http://localhost/test/public/api/ ,
也就是說,在瀏覽器中訪問 localhost:8081/api/books ,前端開發(fā)服務(wù)器就會向 http://localhost/test/public/api/api/books 請求數(shù)據(jù)。就是簡單粗暴地在 target 之后拼接上當(dāng)前的uri。
會發(fā)現(xiàn)這樣子做,實(shí)際的 url 中多了一個(gè) /api ,不滿足我們的需求,所以可以通過 pathRewrite 將這幾個(gè)字符串替換掉。
// 將 "/api" 開頭的 url 中的 "api" 替換成 空 proxyTable: { '/api': { target: 'http://localhost/test/public/api/', pathRewrite: { '^/api': '' } } }, // 根據(jù)上面的規(guī)則 // 當(dāng)在瀏覽器訪問 localhost:8081/api/books // 則實(shí)際訪問的是 http://localhost/test/public/api/books // 假設(shè)設(shè)置成 pathRewrite: {'^/api': '/somethingnew'} // 當(dāng)在瀏覽器訪問 localhost:8081/api/books // 則實(shí)際訪問的是 http://localhost/test/public/somethingnew/books
而配置項(xiàng) changeOrigin: true 則是設(shè)置了前端開發(fā)服務(wù)器向后端發(fā)送請求時(shí) HTTP 包中的 HOST 字段。當(dāng)設(shè)置為 true 時(shí),HOST 會被設(shè)置成目標(biāo)地址(target)中的主機(jī)。當(dāng)后端服務(wù)器是虛擬主機(jī)時(shí),這個(gè)選項(xiàng)顯得尤為重要,或者說,同一個(gè)IP綁定了多個(gè)服務(wù)器服務(wù)時(shí)顯得尤為重要。不設(shè)置的話,可能會導(dǎo)致請求不到數(shù)據(jù)。
更多的 proxyTable 可用參數(shù)可以參考 http-proxy-middleware 的文檔
相關(guān)文章
詳解Vue、element-ui、axios實(shí)現(xiàn)省市區(qū)三級聯(lián)動
這篇文章主要介紹了Vue、element-ui、axios實(shí)現(xiàn)省市區(qū)三級聯(lián)動,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05Vite3結(jié)合Svelte3使用@import導(dǎo)入scss樣式
這篇文章主要為大家介紹了Vite3結(jié)合Svelte3使用@import導(dǎo)入scss樣式實(shí)現(xiàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06VUE3.2項(xiàng)目使用Echarts5.4詳細(xì)步驟總結(jié)
Vue3.2是一款非常流行的JavaScript框架,它讓在前端領(lǐng)域開發(fā)變得更加的便捷,下面這篇文章主要給大家介紹了關(guān)于VUE3.2項(xiàng)目使用Echarts5.4的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06vueCli?4.x升級5.x報(bào)錯(cuò):Progress?Plugin?Invalid?Options的解決方法
本文主要介紹了vueCli?4.x升級5.x報(bào)錯(cuò):Progress?Plugin?Invalid?Options的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01淺析vue-router jquery和params傳參(接收參數(shù))$router $route的區(qū)別
今天做項(xiàng)目時(shí)踩到了vue-router傳參的坑(jquery和params),所以決定總結(jié)一下二者的區(qū)別。感興趣的朋友跟隨腳本之家小編一起看看吧2018-08-08VUE項(xiàng)目axios請求頭更改Content-Type操作
這篇文章主要介紹了VUE項(xiàng)目axios請求頭更改Content-Type操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07vue中使用v-for時(shí)為什么不能用index作為key
這篇文章主要介紹了vue中使用v-for時(shí)為什么不能用index作為key,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04詳解如何在vue項(xiàng)目中引入elementUI組件
這篇文章主要介紹了詳解如何在vue項(xiàng)目中引入elementUI組件,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02