vue項目如何去掉URL中#符號的方法
前言
最近,同事跟我說,項目的訪問路徑裡的/#/挺不美觀的,就下手嘗試去掉,本以為就是一句代碼搞定的事情,結果遇到不少問題。
現在把我遇到的情況記錄下來,做個存檔,如果看到文章的有緣人剛好遇到跟我一樣的情況,我的內容能提供多一個解決方案也是不錯的。
正常解決步驟
1. 設置路由mode
router的默認mode為hash模式,關於hash模式,官方文檔這樣描述:
它在內部傳遞的實際 URL 之前使用瞭一個哈希字符(#)。由於這部分 URL 從未被發送到服務器,所以它不需要在服務器層面上進行任何特殊處理。不過,它在 SEO 中確實有不好的影響。如果你擔心這個問題,可以使用 HTML5 模式。
– — 《Vue Router官方文檔》
而關於history模式,官方文檔是這樣說的:
當使用這種歷史模式時,URL 會看起來很 “正常”,例如 https://example.com/user/id。漂亮!
這正符合我們的需求。於是在我們的項目中啟動路由mode的history模式:
let Router = new VueRouter({ mode: 'history', routes: [...] ... });
2. 配置服務端nginx
關於history模式,官方文檔還提到:
不過,問題來瞭。由於我們的應用是一個單頁的客戶端應用,如果沒有適當的服務器配置,用戶在瀏覽器中直接訪問 https://example.com/user/id,就會得到一個 404 錯誤。這就醜瞭。
不用擔心:要解決這個問題,你需要做的就是在你的服務器上添加一個簡單的回退路由。如果 URL 不匹配任何靜態資源,它應提供與你的應用程序中的 index.html 相同的頁面。漂亮依舊!
按步驟1修改完,部署到服務器之後,URL中的#確實沒有瞭,但是當刷新頁面,或者頁面中有使用window.open打開的頁面時,會出現404錯誤。
按官方文檔的說明,需要配置服務器的回退路由,我們的環境是使用的nginx,使用以下配置解決瞭刷新404的問題
location / { try_files $uri $uri/ @router; index index.html index.htm app.html app.htm; } location @router { rewrite ^.*$ /index.html break; }
如果你的環境是apache或者其他服務器,可以參考官方文檔進行配置
可能碰到的問題
1. 靜態資源Uncaught SyntaxError: Unexpected token < 問題
我的項目中有用使用相對路徑獲取靜態資源,例如 <img src="./img/xxxx.png" /> 這種方式展示的圖片,這時候這些圖片都會拋出 Uncaught SyntaxError: Unexpected token < 404找不到資源的異常,這是由於啟用history模式後相對路徑造成的問題,將 vue.config.js 文件中 publicPath 或者 bashUrl 從./ 相對路徑修改為 / 絕對路徑即可
publicPath = '/';
我的項目環境中 http://localhost:8080/ 後沒有需要添加固定的路徑,如果你的有(比如 http://localhost:8080/domain/),需要按你的情況進行調整
2. api接口請求404問題
項目部署之後,我發現有些接口請求出現瞭404的情況,檢查發現 api 的axios 配置時的路徑配置存在相對路徑的使用,需要進行修改
調整之前的配置:
export const exampleApi = (id) => { return request({ url: 'xxx/xxx/' + id, method: 'get', }) }
配置修改為:
export const exampleApi = (id) => { return request({ url: '/xxx/xxx/' + id, method: 'get', }) }
3. 開發環境(npm run dev啟動)刷新404的問題
這個問題困擾我不少時間,網上也沒有找到網友有類似的情況,最後發現是因為開發環境調試時,為瞭解決跨域問題,在項目中配置瞭 webpack devServer 的 proxy,代理處理瞭所有的請求,通過使用 bypass 繞過html,就可以解決此問題
# vue.config.js文件 devServer: { proxy: { '/': { target: url, ... bypass: function (req, res, proxyOptions) { if (req.headers.accept.indexOf('html') !== -1) { console.log('Skipping proxy for browser request.'); return '/index.html'; } }, }, } }
4. 前端路由與服務端接口路由沖突問題
前面三個問題解決後,本來以為已經全部正常。但是再測試發現,部分頁面刷新仍然會出現問題,但是通過前端的排查未能發現原因。直到檢查到nginx的配置時,發現這些出錯誤的頁面的路由,與服務端的接口路由似乎是重合的!這些前端頁面的路由被nginx匹配到服務端的路由,轉發到服務端去處理,所以發生異常瞭!
解決問題的思路為,前端程序中給所有的接口添加統一的路由前綴入口,nginx轉發時匹配這個統一的前綴即可。
axios.js:
# 設置bashURL axios.defaults.baseURL = "/api";
nginx配置文件:
location ^~ /api/ { proxy_pass http://pig-gateway:9999/; # proxy_set_header Host $http_host; proxy_connect_timeout 60s; proxy_send_timeout 45s; proxy_read_timeout 450s; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
開發環境跨域設置調整
vue.config.js:
devServer: { ... proxy: { ... '/api': { target: url, changeOrigin: true, logLevel: 'debug' }, }, ... }
結尾
至此,我的項目終於在生產環境以及開發環境都運行正常瞭
到此這篇關於vue項目如何去掉URL中#符號的文章就介紹到這瞭,更多相關vue去掉URL中#內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Nginx報404錯誤的詳細解決方法
- Nginx解決history模式下頁面刷新404問題示例
- vue-router如何實現history模式配置
- vue項目打包發佈後接口報405錯誤的解決
- vuecli3打包後出現跨域問題,前端配置攔截器無效的解決