Spring Boot + Vue 這一對技術棧目前看來可以說是非常的火熱,關于 Spring Boot 松哥已經寫過多篇教程,公號后臺回復 666 可以獲取 PDF 鏈接。
前后端分離的文章也寫過好幾篇了,例如:
- 一個JAVA程序猿眼中的前后端分離以及Vue.js入門
- 前后端分離開發思路探討
- 前后端分離時代,Java 程序員的變與不變!
相信大家也從中學到了不少干貨。
老實說,前后端分離其實并不難,前后端分離之后,Java 工程師只需要專心寫接口就可以了,在我看來工作可比以前輕松多了。
如果讓一個專業的前端工程師來寫前端頁面,其實也不難,Vue 算是三大前端框架中最容易上手的了。
那怎么樣就有難度了呢?
讓同一個人既寫前端又寫后端!
我知道很多小伙伴在這里總是想不通,很多人 clone 了松哥在 GitHub 上的開源項目下來之后,問的最多的問題就是前后端是怎么通信的?跨域是怎么解決的?剛好松哥最近在這里踩了個坑,就來和大家聊一聊這個問題。
不是跨域的跨域
如果你直接在項目中引入 Vue,像用 jQuery 那樣用 Vue,那沒什么問題,你應該也不會有跨域的疑問。但是如果你做的是單頁面應用(SPA),那么必然會有這樣的疑問,跨域問題怎么搞!
因為在單頁面應用中,前端項目可以單獨通過 node 啟動,它單獨占用一個端口,后端項目啟動后也是另外一個端口,此時從前端發送請求到后端,由于兩者處于不同的端口之上,因此必然存在一個跨域問題。
但是大家想想,這個跨域有可能只是在開發環境下存在,生產環境下有可能不存在。因為當項目開發完成之后,我們對前端項目進行打包,打包后部署在 Nginx 上或者直接拷貝到后端項目中運行都可以(一般使用前者):
- 如果是前者,后端接口也通過 Nginx 進行映射,這個時候就不會存在跨域問題了
- 如果是后者,那就更簡單了,部署的時候前后端代碼放在一起,更不會有跨域問題了
因此,解決這個所謂的 “跨域” 問題,我們不能按照傳統的思路來(通過 JSONP 或者 CORS),因為在項目真正上線后,所謂的跨域問題可能就會消失。
那么這個問題怎么解決呢?我們可以在前端 nodejs 中配置請求轉發。
配置請求轉發其實不難,不過 vue-cli2 和 vue-cli3 的寫法稍有不同,這也是我前一段時間踩坑的地方。
vue-cli2 方案
如果我們使用的 vue-cli2 來創建的 SPA 應用,創建成功之后,在項目的 config 目錄下有一個 index.js 文件,在這個文件中,我們可以進行請求轉發配置,如下圖:
配置內容如下:
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/': {
target: 'http://localhost:8082',
changeOrigin: true,
pathRewrite: {
'^/': ''
}
},
'/ws/*': {
target: 'ws://127.0.0.1:8082',
ws: true
}
},
...
}
proxyTable 就是我們配置的轉發路由表。這個里邊我們一共配置了兩個規則:
- 第一個是攔截所有 HTTP 請求,將之轉發到后端服務器上(前端默認端口是 8080),后端的端口是 8082。至于攔截規則 / ,大家可以自定義,根據實際情況來寫,例如所有的 HTTP 請求都有一個統一的前綴 api,那么這里就可以寫 /api。
- 第二個是攔截所有的 websocket 請求進行轉發,我這里給所有的 websocket 請求取了一個統一的前綴 /ws
如果你有更多的攔截規則,繼續在這里配置就可以了,這些配置只會在開發環境下生效,當項目編譯打包時,這些配置是不會打包進去的,也就是說,項目發布的時候,這些配置是失效的,這個時候我們通過 Nginx 或者將前端代碼拷貝到后端,就可以解決生產環境下的跨域問題了(相當于開發時候的跨域在生產環境下不存在)。
相對來說,vue-cli2 在這里的配置還比較容易。
vue-cli3 方案
vue-cli3 去年出來后,當時就嘗了一把鮮,但是可能 vue-cli2 用久了,一時半會還不愿意接受 vue-cli3 ,于是嘗鮮完了之后就放下了,沒怎么用了。直到前兩天,新項目嘗試了一下 vue-cli3,結果在請求轉發這塊就掉坑里了。
一開始沒多想,還是 vue-cli2 里邊的老辦法,只不過是在 vue-cli3 創建的項目的 vue.config.js 文件中進行配置,文件位置如下圖:
注意,使用 vue-cli3 創建的 SPA 應用,沒有 config 目錄了,因此請求轉發的配置我們要在 vue.config.js 這個配置文件中來配置。
一開始我直接把 vue-cli2 中的請求轉發配置拷貝過來,這樣發送 HTTP 請求倒是沒問題,但是 websocket 請求一直有問題,后來經過仔細分析,發現這兩者在請求轉發配置上有一點點差異,我們來看看 vue-cli3 中的請求轉發配置(這也是我這里 vue.config.js 文件的完整內容);
let proxyObj = {};
proxyObj['/ws'] = {
ws: true,
target: "ws://localhost:8081"
};
proxyObj['/'] = {
ws: false,
target: "http://localhost:8081",
changeOrigin: true,
pathRewrite: {
'^/': ''
}
};
module.exports = {
devServer: {
host: 'localhost',
port: 8080,
proxy: proxyObj
}
}
首先我們創建一個 proxyObj 用來放各種代理對象,至于代理的內容這里的則和 vue-cli2 中的沒有太多差異。要注意的是,HTTP 請求代理中,多了一個屬性 ws: false,用過 vue-cli3 同學可能發現了,如果不加這個屬性,瀏覽器控制臺會一直報連不上 socket 的錯,加上就沒事了。
最后在 devServer 中指定項目的 host 和 port ,然后再配置一下 proxy 對象就可以啦。
這就是我們在 vue-cli3 中請求的配置。
不過這里的配置老實說沒有什么難度,做過一次就會啦,要是沒做過,頭一次可能得折騰半天。
結語
很多小伙伴一直對于前后端分離開發,前后端請求是如何對接的一直有疑問,希望這篇文章能夠給你一些啟發。如果看懂了,可以點個在看或者轉發支持下哦。