我們知道前端常用的有Hash 模式和html5模式的路由,hash模式在nginx上部署不需要額外的操作,而html5模式則需要額外設置,這里介紹下如何在nginx根地址(location / {})下部署和在非根地址上(location /admin{})部署。
在這之前,我先說一下 為什么html5路由需要在nginx上配置,我們知道,vue-router就是用來處理路由的,我我們在瀏覽器上輸入地址時,這時候,html5是通過瀏覽器的history api 來處理地址,但是,這出現了一個問題,當瀏覽器訪問地址時,這時候,服務器上第一個接受這個地址的時nginx,nginx在沒有我們配置的情況下,自己把這個地址給處理了,假設,我們發送的是www.abc.com/home,nginx收到這個地址第一件事不是把這個地址轉給我們打包的前端的router來處理,而是自己處理,自己先找你有沒有在nginx上配置這個home文件或目錄,如果沒有,直接就返回404,我們要做的是,在nginx上設置,不管你接收到什么地址,全部交給前端處理,也就是vue-router。
?1.根地址如何部署html5路由
? ? ? ? 1.1 在項目打包部署前,我們確定我們要做的是部署在說明地址上,在vue-router的配置里,配置了路由模式后,我們要對路由模式進行處理。在createWebHistory('/')上插入地址,告訴router,基礎路由是這個,后續的路由都是在這個地址后面運行。代碼如下:
import { createRouter, createWebHistory } from "vue-router";
const headline=" |"
const router = createRouter({history: createWebHistory('/'), //告訴router 我們后續的路由是以這個為基礎,就是以根地址為基礎運行routes: [{ path: '/:pathMatch(.*)*', redirect:"/",name:"404"}, //解決history模式下的路由無法匹配問題{path: "/",name: "index",component: () => import("../views/BaseLayout.vue"),children: [{path: "",name: "home",component: () => import("../views/home/HomeView.vue"),meta: { title: `首頁${headline}` },},{path: "/forum",name: "forum",component: () => import("../views/forum/ForumView.vue"),meta: { title: `關于論壇${headline}` },},{path: "/journalism",name: "journalism",component: () => import("../views/journalism/JournalismView.vue"),meta: { title:`新聞中心${headline}` },},{path: "/partner",name: "partner",component: () => import("../views/partner/PartnerView.vue"),meta: { title:`合作伙伴${headline}` },},{path: "/territory",name: "territory",component: () => import("../views/territory/TerritoryView.vue"),meta: { title:`關注領域${headline}` },},],},],scrollBehavior (to, from, savedPosition){return { top: 0 }},
});
router.beforeEach((to: object | any, from, next) => {//beforeEach是router的鉤子函數,在進入路由前執行if (to.meta.title) {//判斷是否有標題document.title = to.meta.title;}next(); //執行進入路由,如果不寫就不會進入目標頁
});router.afterEach((to, from) => {})
export default router;
? ? ? ? 1.2 當我們在router上配置后就可以打包,然后就可以配置nginx了,在nginx上,我們要告訴nginx,你收到什么路由,除了和自己有關的地址,其他的你全部轉給前端的router來處理。
????????
location / { #/是nginx要管的,其他的nginx全部轉給前端來處理root /data/dist; try_files $uri $uri/ /index.html; #這里告訴nginx如果用戶訪問的是你沒有配置的地址,你全轉給前端的router,這個index.html是前端的入口文件。index index.html index.htm;}
? ? ? ? 到這里之后,根地址的html5路由已經部署在nginx上,也不會出現刷新后404的問題了
?2.非根地址如何部署html5路由?
? ? ? ? 非根路路由下要稍微復雜一點,假設我們要把資源部署在www.sss.com/admin地址下,其中的admin就是非根地址。
? ? ? ? 1.1 首先 我們也是需要在router上配置地址,也是告訴router,我們后續的路由要在/admin的地址上運行,防止和nginx上形成沖突。代碼如下
import { createRouter, createWebHistory } from "vue-router";
const headline=" |"
const router = createRouter({history: createWebHistory('/admin'), //告訴router 我們后續的路由是以這個為基礎,就是以根地址為基礎運行routes: [{ path: '/:pathMatch(.*)*', redirect:"/",name:"404"}, //解決history模式下的路由無法匹配問題{path: "/",name: "index",component: () => import("../views/BaseLayout.vue"),children: [{path: "",name: "home",component: () => import("../views/home/HomeView.vue"),meta: { title: `首頁${headline}` },},{path: "/forum",name: "forum",component: () => import("../views/forum/ForumView.vue"),meta: { title: `關于論壇${headline}` },},{path: "/journalism",name: "journalism",component: () => import("../views/journalism/JournalismView.vue"),meta: { title:`新聞中心${headline}` },},{path: "/partner",name: "partner",component: () => import("../views/partner/PartnerView.vue"),meta: { title:`合作伙伴${headline}` },},{path: "/territory",name: "territory",component: () => import("../views/territory/TerritoryView.vue"),meta: { title:`關注領域${headline}` },},],},],scrollBehavior (to, from, savedPosition){return { top: 0 }},
});
router.beforeEach((to: object | any, from, next) => {//beforeEach是router的鉤子函數,在進入路由前執行if (to.meta.title) {//判斷是否有標題document.title = to.meta.title;}next(); //執行進入路由,如果不寫就不會進入目標頁
});router.afterEach((to, from) => {})
export default router;
? ? ? ? ? 1.2 配置靜態文件路徑,防止因為nginx改了地址,導致請求不到靜態資源,在vite.config.ts里添加base:"/admin" ,這里建議使用變量,防止漏改。代碼如下:
export default defineConfig({base:"/admin", #和我們nginx配置的非根地址一致,防止靜態資源404plugins: [vue(),],assetsInclude: ['**/*.png', '**/*.jpg'],
})
? ? ? ? 1.3當前端配置好打包后,在nginx上要配置我們的非根地址,和指向index.html,多的不說,全在代碼里,這里要注意下,當nginx配置非根路由時,我們不能用root來綁定前端包了,而是要用alias
location /admin { #定義好我們的非根地址,這里要注意與router里的一致,防止沖突alias /data/dist;try_files $uri $uri/ /admin/index.html; #因為前端的base里定義了admin,所以這里要加上,防止404index index.html index.htm;}
? ? ? ? 部署好后重啟nginx,然后就可以訪問多個項目啦 如www.aaaa.com 是客戶端項目 www.aaa.com/admin是管理員端項目 www.aaa.com/user 是內部端項目,拜