vue router mode模式在webpack 打包上線問題
vue-router mode模式有兩種 hash和history。
1.hash —— 即位址列 URL 中的 # 符號。
比如這個 URL:http://www.abc.com/#/hello,hash 的值為 #/hello。它的特點在於:hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,對後端完全沒有影響,因此改變 hash 不會重新載入頁面。
2.history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定瀏覽器支援)
這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的 back、forward、go 的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會立即向後端傳送請求。
hash 模式和 history 模式都屬於瀏覽器自身的特性,Vue-Router 只是利用了這兩個特性(通過呼叫瀏覽器提供的介面)來實現前端路由。
一般專案上vue-router mode模式預設為hash,也可以設定history。
config資料夾下 index.js
問題
當mode 模式為history,使用vue-cli構建專案, 打包 npm run build ,dist資料夾下 有index.html和static資料夾。
build: { //打包時的index放置位置 index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory:'static', //公共資源路徑 assetsPublicPath: '/', productionSourceMap: true, devtool: '#source-map', productionGzip: false, productionGzipExtensions: ['js', 'css'], bundleAnalyzerReport: process.env.npm_config_report } }
裡面 assetsPublicPath: '/', /
開頭路徑固定以根目錄為起點。公共資源請求路徑是從伺服器根目錄開始。
1.當專案檔案放到根目錄
正常情況,大家專案檔案都會放在伺服器的根目錄,當專案檔案(index.html static)放在根目錄時。
如伺服器網址 https://xxxxx.com 的根目錄 https://xxxxx.com/index.html
請求css檔案路徑 https://xxxxx.com/static/css/app.cca059254702f9ed953b7df749673cf4.css
2.專案檔案放到根目錄下的子資料夾
當專案檔案(index.html static)放到根目錄下的子資料夾時。
例如 專案資料夾名 myprojct 訪問index檔案路徑為https://xxxxx.com/myprojct/index.html 且assetsPublicPath: '/'
則index.html資料夾所依賴的 css js img 的請求路徑 依舊是從專案根目錄 https://xxxxx.com/static/css/app.cca059254702f9ed953b7df749673cf4.css
導致資源無法訪問。
解決途徑:confing index.js 改為assetsPublicPath: './' 把絕對路徑改為使用相對路徑來訪問依賴檔案
history模式問題
通過history api,我們丟掉了醜陋的#,但是它也有個毛病:
不怕前進,不怕後退,就怕重新整理,f5,(如果後端沒有準備的話),因為重新整理是實實在在地去請求伺服器的,不玩虛的。
在hash模式下,前端路由修改的是#中的資訊,而瀏覽器請求時是不帶它玩的,所以沒有問題.但是在history下,你可以自由的修改path,當重新整理時,如果伺服器中沒有相應的響應或者資源,會分分鐘刷出一個404來。
所以,如果你想在github.io上搭一個單頁部落格,就應該選擇hash模式。比如這個部落格
404錯誤
在History mode下,如果直接通過位址列訪問路徑,那麼會出現404錯誤,這是因為這是單頁應用(廢話)…其實是因為呼叫了history.pushState API 所以所有的跳轉之類的操作都是通過router來實現的,解決這個問題很簡單,只需要在後臺配置如果URL匹配不到任何靜態資源,就跳轉到預設的index.html。具體配置如下:
//Apache <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] </IfModule> //nginx location / { try_files $uri $uri/ /index.html; }