Vue使用vue-recoure + http-proxy-middleware + vuex配合promise實現(xiàn)基本的跨域請求封裝
使用vue init webpack 你的項目名稱初始化一個vue的項目
- 安裝依賴
npm install vue-resource http-proxy-middleware vuex koa - 在項目的main.js中引入并注冊下載的依賴
- 在main.js中引入vue-resource并注冊到vue實例中
import VueResource from 'vue-resource' //用來請求接口 Vue.use(VueResource) //開啟后請求就會以application/x-www-form-urlencoded作為MIME type 就像普通的html表單一樣,form形式傳給后臺,而非JSON Vue.http.options.emulateJSON = true;
在main.js文件同級創(chuàng)建一個store的文件夾用來存放vuex的文件
在store文件夾中創(chuàng)建一個index.js的文件(vue在查找時會自動查找這個文件),在文件中創(chuàng)建store實例并導(dǎo)出
import Vue from 'vue'
import VueX from 'vuex'
import actions from './actions' //這里為了可擴展性,所以單獨創(chuàng)建一個文件用來存放請求方法
Vue.use(VueX);
//請求之甬道actions所以只導(dǎo)入了actions
export default new VueX.Store({
actions
});
在store文件夾中創(chuàng)建一個actions.js的文件用來存放請求方法

配置請求代理
在config文件夾下面創(chuàng)建一個host.js文件用來存放開發(fā)、測試、生產(chǎn)的請求地址ip

在文件中你可以根據(jù)條件來配置到底是開發(fā)還是測試或者是正式環(huán)境
let HostType = 0; //用來判斷當(dāng)前是什么環(huán)境
let Host = {}; //用來存儲當(dāng)前環(huán)境的請求ip
if (HostType == 0) {
Host = { //對象內(nèi)的字段可以自定義如果整個項目只有一個后臺地址只需要一個字段就可以;
api: "127.0.0.1:9000",
base: "",
fileUp: ""
}
} else if (HostType == 1) {
Host = {
...
}
} else if (HostType == 2) {
Host = {
...
}
}
module.exports = Host;
在config文件夾下面創(chuàng)建一個proxy-table.js文件用來存放代理的配置
const HOST = require("./HOST.js");
module.exports = {
//接口代理
"/api/text": {
target: HOST.api, //需要代理到那個地址
changeOrigin: true //是否跨域
},
"/api/demo": {
target: HOST.api,
changeOrigin: true
}
}
在config文件夾下面創(chuàng)建一個proxy-middleware.js憑借代理和注冊
//導(dǎo)入插件
const proxyMiddleware = require("http-proxy-middleware");
//導(dǎo)入代理的配置
const proxyTable = require("./proxy-table");
//拿出配置代理的所有匹配的字段
const proxyContext = Object.keys(proxyTable); // ["/api/text","/api/demo"]
module.exports = () => {
//創(chuàng)建一個默認(rèn)的配置對象
const defautOptions = {
changeOrigin: true,
secure: false
}
//為什么return的是一個async的方法是因為請求代理是通過服務(wù)器進行代理的在啟動腳本中會使用koa框架來注冊這個中間件
return async (ctx, next) => { //ctx和next都是koa框架中間件自帶的參數(shù)
for (let context of proxyContext) { //循環(huán)我們拿到的keys數(shù)組
if (ctx.url.startsWith(context)) { //判斷當(dāng)前請求的url中是不是以拿到的keys數(shù)組中的某個值開頭的
ctx.respond = false; //繞開koa框架的內(nèi)置response處理
let options = proxyTable[context];
//如果拿取到的直接是IP地址就賦值給配置對象
if (typeof options === 'string') {
options = {
target: options
}
}
//使用Object.assign()方法合并兩個對象
options = Object.assign({},defautOptions,options);
//將每一個代理都注冊,這里必須return一個自執(zhí)行函數(shù)否則代理不會設(shè)置成功
proxyMiddleware(context,options)(ctx.req,ctx.res, next);
}
}
await next();
}
}
在項目的更目錄中創(chuàng)建一個服務(wù)啟動的文件腳本名字自定義
//在腳本文件中導(dǎo)入我們需要的框架和代理配置文件
const Koa = require("koa"); //所用的框架
const proxy = require("./config/proxy-middleware"); //剛才創(chuàng)建的代理配置文件
//創(chuàng)建一個服務(wù)
const app = new Koa();
//將代理插件注冊到服務(wù)上
app.use(proxy()); //因為我們導(dǎo)出的是一個方法所以需要使用調(diào)用的方式注冊
//啟動服務(wù)
app.listen(9000,() => {
console.log("server running at http://127.0.0.1:9000");
});
//對koa框架不是熟悉的可以使用express框架 如果使用express框架拿代理就不用使用前面那樣復(fù)雜的寫法了
const express = require("express");
const proxy = require("http-proxy-middleware");
const app = express();
app.use(express.static("dist/"));
app.use("/all", proxy({
target: "http://127.0.0.1:3000",
changeOrigin: true,
}))
app.listen(9000, (err) => {
if (err) return console.log(err);
console.log("app as running at http://127.0.0.1:9000");
})
代理配置好以后就可以寫請求方法了,在創(chuàng)建好的store文件夾下面的actions文件里編寫請方法
//導(dǎo)入Vue
import Vue from "vue"
export default {
//測試接口
testInterface({},postdata) {
//postdata是你調(diào)用的時候傳過來的參數(shù)可以更具需求拼接接口
//let ipstr = `/api/text?id=${postdata.id}`;
//return Vue.http.get(ipstr,{}).then(response => {
return Vue.http.get("/api/text",{}).then(response => {
if (response.status == 200) {
return new Promise(response.body);
} else {
return new Promise(response.data.message);
}
})
}
}
測試代理是否成功
<div id="app"> <button @click="clickF">按鈕</button> </div>
首先在script標(biāo)簽里面將vuex導(dǎo)入進來
import {mapActions} from "vuex";
在methods中創(chuàng)建一個方法用來發(fā)送請求,并在methods的最下面使用結(jié)構(gòu)函數(shù)將我們存在vuex中的請求方法按需導(dǎo)入
methods: {
clickF() {
this.testInterface().then(data=> {
console.log(data);
})
},
...mapActions(["testInterface"])
}
直接使用this.方法名就可以訪問到vuex中的actions方法;這里使用的是輔助函數(shù),也可以使用原始方法
在終端中使用node 啟動腳本文件的名稱 或者使用 nodemon 啟動腳本文件的名稱

在瀏覽器中打開服務(wù)的地址點擊我們創(chuàng)建的按鈕查看請求接口

可以看到我們的代理是請求成功的;狀態(tài)之所以是304是因為第二次請求的時候如果請求沒有發(fā)生改變就會使用瀏覽器緩存;
上面遺留了一個bug就是這個方法只適用于build后的項目;在開發(fā)中每次都build無疑浪費了很多時間,下面就來在開發(fā)環(huán)境中使用服務(wù)器代理的方式完成跨域請求
如果是cli創(chuàng)建的項目直接在config文件夾下面的index文件中的proxyTable進行添加就可以了

相關(guān)文章
Vue自定義指令結(jié)合阿里云OSS優(yōu)化圖片的實現(xiàn)方法
這篇文章主要介紹了Vue自定義指令結(jié)合阿里云OSS優(yōu)化圖片的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
使用element-ui,el-row中的el-col數(shù)據(jù)為空頁面布局變亂問題
這篇文章主要介紹了使用element-ui,el-row中的el-col數(shù)據(jù)為空頁面布局變亂問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
vue基于Element按鈕權(quán)限實現(xiàn)方案
這篇文章主要介紹了vue基于Element按鈕權(quán)限實現(xiàn)方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
Vue.js實現(xiàn)簡單動態(tài)數(shù)據(jù)處理
本篇文章主要介紹了Vue.js實現(xiàn)簡單動態(tài)數(shù)據(jù)處理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
Springboot+Vue-Cropper實現(xiàn)頭像剪切上傳效果
這篇文章主要為大家詳細(xì)介紹了Springboot+Vue-Cropper實現(xiàn)頭像剪切上傳效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08

