const router=new VueRouter({
base: process.env.BASE_URL,
//hash模式下部署到服務器訪問沒問題,history就不行,需要在服務器上配置
mode: 'history',
routes
})
module.exports={
lintOnSave: false,
publicPath: process.env.VUE_APP_PATH,
// publicPath : process.env.NODE_ENV==='production' ? './' : '/',
outputDir: 'dist',
devServer: {
disableHostCheck: true,
// overlay: { // 讓瀏覽器 overlay 同時顯示警告和錯誤
// warnings: true,
// errors: true
// },
https: false, // https:{type:Boolean}
open: false, //配置后自動啟動瀏覽器
hotOnly: true, // 熱更新
proxy: { //配置多個代理
"/api": {
target: "http://192.168.2.241",
changeOrigin: true,
ws: true, //websocket支持
secure: false,
},
}
},
}
404報錯原因:
當我們設置了mode為history時,當前端發送路徑給服務端時,服務端根本就不認識省去#的url,所以返回給我們404,因為vue是單一頁面所有的頁面都在index.html中,vue是用js來切換頁面的,具體的解釋看vue官網
解決辦法:
nginx服務器修改
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.html?s=/$1 last;
break;
}
}
前后端分離開發模式下,前后端是獨立部署的,前端只需要將最后的構建物上傳至目標服務器的web容器指定的靜態目錄下即可
我們知道vue項目在構建后,是生成一系列的靜態文件
常規部署我們只需要將這個目錄上傳至目標服務器即可
// scp 上傳 user為主機登錄用戶,host為主機外網ip, xx為web容器靜態資源路徑
scp dist.zip user@host:/xx/xx/xx
讓web容器跑起來,以nginx為例
server {
listen 80;
server_name www.xxx.com;
location / {
index /data/dist/index.html;
}
}
配置完成記得重啟nginx
// 檢查配置是否正確
nginx -t
// 平滑重啟
nginx -s reload
操作完后就可以在瀏覽器輸入域名進行訪問了
當然上面只是提到最簡單也是最直接的一種布署方式
什么自動化,鏡像,容器,流水線布署,本質也是將這套邏輯抽象,隔離,用程序來代替重復性的勞動,本文不展開
這是一個經典的問題,相信很多同學都有遇到過,那么你知道其真正的原因嗎?
我們先還原一下場景:
先定位一下,HTTP 404 錯誤意味著鏈接指向的資源不存在
問題在于為什么不存在?且為什么只有history模式下會出現這個問題?
Vue是屬于單頁應用(single-page application)
而SPA是一種網絡應用程序或網站的模型,所有用戶交互是通過動態重寫當前頁面,前面我們也看到了,不管我們應用有多少頁面,構建物都只會產出一個index.html
現在,我們回頭來看一下我們的nginx配置
server {
listen 80;
server_name www.xxx.com;
location / {
index /data/dist/index.html;
}
}
可以根據 nginx 配置得出,當我們在地址欄輸入 www.xxx.com 時,這時會打開我們 dist 目錄下的 index.html 文件,然后我們再跳轉路由進入到 www.xxx.com/login
關鍵在這里,當我們在 website.com/login 頁執行刷新操作,nginx location 是沒有相關配置的,所以就會出現 404 的情況
router hash 模式我們都知道是用符號#表示的,如 website.com/#/login, hash 的值為 #/login
它的特點在于:hash 雖然出現在 URL 中,但不會被包括在內 HTTP 請求中,對服務端完全沒有影響,因此改變 hash 不會重新加載頁面
hash 模式下,僅 hash 符號之前的內容會被包含在請求中,如 website.com/#/login 只有 website.com 會被包含在請求中 ,因此對于服務端來說,即使沒有配置location,也不會返回404錯誤
那么vue-router的hash模式和histroy模式有什么區別呢?
1、hash模式url帶#,histroy模式url不帶#
2、hash模式解決了通過http請求來切換頁面,改變路徑可以直接改變頁面,無需進行網絡請求,這叫前端路由,在hash模式下改變的是#中的信息,
history模式,可以前進和后退,但是不能刷新頁面,刷新之后就會報錯。如果后端沒有對路由地址進行相應的處理,那么就會報404的錯。
3、hash瀏覽器支持率比較好,支持低版本的瀏覽器,但history的方法只支持部分瀏覽器。
看到這里我相信大部分同學都能想到怎么解決問題了,
產生問題的本質是因為我們的路由是通過JS來執行視圖切換的,
當我們進入到子路由時刷新頁面,web容器沒有相對應的頁面此時會出現404
所以我們只需要配置將任意頁面都重定向到 index.html,把路由交由前端處理
對nginx配置文件.conf修改,添加try_files $uri $uri/ /index.html;
server {
listen 80;
server_name www.xxx.com;
location / {
index /data/dist/index.html;
try_files $uri $uri/ /index.html;
}
}
修改完配置文件后記得配置的更新
nginx -s reload
這么做以后,你的服務器就不再返回 404 錯誤頁面,因為對于所有路徑都會返回 index.html 文件
為了避免這種情況,你應該在 Vue 應用里面覆蓋所有的路由情況,然后再給出一個 404 頁面
const router=new VueRouter({
mode: 'history',
routes: [
{ path: '*', component: NotFoundComponent }
]
})
關于后端配置方案還有:Apache、nodejs等,思想是一致的,這里就不展開述說了
給大家分享我收集整理的各種學習資料,前端小白交流、學習交流,也可以直接問我,我會組織大家一起做項目練習,幫助大家匹配一位學習伙伴互相監督學習-下面是學習資料參考。
前端學習交流、自學、學習資料、新手入門教程,自學教程等推薦
戶反映:說自己的網站走nginx代理后,打開空白。直接IP加地址訪問是好的(http://ip:port)
故障排查:
1、打開chrome瀏覽器,訪問了下,訪問情況真是客戶描述的那樣。
2、感覺打開chrome ,開發者工具,發現部分請求URL是404,css和js的
3、找客戶要服務器登錄的賬號,檢查nginx配置文件
upstream www.test.com{ server 127.0.0.1:8080; } server { listen 80; listen 443 ssl http2; ssl_certificate /usr/local/nginx/conf/ssl/www.test.com.pem; ssl_certificate_key /usr/local/nginx/conf/ssl/www.test.com.key; server_name www.test.com; access_log /data/wwwlogs/www.test.com_nginx.log combined; index index.html index.htm index.jsp; root /data/wwwroot/www.test.com; location ~ .*\.(js|css)?$ { expires 7d; access_log off; } ? location / { proxy_pass http://www.test.com; include proxy.conf; } }
4、大家有發現上面配置有問題不?剛開始我也沒有注意,自認為配置文件是對 的。
打算檢查nginx的日志,一遍請求URL,一遍查看nginx果然還是404.(感覺疑惑),明明配置了proxy_pass http://www.test.com。
故障原因:
是因為 “location ~ .*\.(js|css)?$” 這個匹配攔截掉了,請求不能正常發往下一個“location /” ,也就不能正常抵達后端proxy_pass了。
解決方法:
第一種解決方法:是將后端的靜態文件(css 和js ),放入前置nginx 機器/data/wwwroot/www.test.com
第二種解決方法 :修改配置文件
upstream www.test.com{ server 127.0.0.1:8080; } server { listen 80; listen 443 ssl http2; ssl_certificate /usr/local/nginx/conf/ssl/www.test.com.pem; ssl_certificate_key /usr/local/nginx/conf/ssl/www.test.com.key; server_name www.test.com; access_log /data/wwwlogs/www.test.com_nginx.log combined; index index.html index.htm index.jsp; root /data/wwwroot/www.test.com; ? location ~ .*\.(js|css)?$ { proxy_pass http://www.test.com; expires 7d; access_log off; } ? location / { proxy_pass http://www.test.com; include proxy.conf; } }
?
??此賬號為華為云開發者社區官方運營賬號,提供全面深入的云計算前景分析、豐富的技術干貨、程序樣例,分享華為云前沿資訊動態
本文分享自華為云社區《學習VueRouter,HTML5 History 模式,因為history模式刷新頁面會出現404》,作者: DevFeng 。
vue-router 默認 hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL,于是當 URL 改變時,頁面不會重新加載。
如果不想要很丑的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新加載頁面。
const router=new VueRouter({
mode: 'history',
routes: [...]
})
當你使用 history 模式時,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!
不過這種模式要玩好,還需要后臺配置支持。因為我們的應用是個單頁客戶端應用,如果后臺沒有正確的配置,當用戶在瀏覽器直接訪問 http://oursite.com/user/id 就會返回 404,這就不好看了。
所以呢,你要在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。
注意:下列示例假設你在根目錄服務這個應用。如果想部署到一個子目錄,你需要使用 VueCLI 的
publicPath 選項 (opens new window)和相關的 router base property (opens new window)。你還需要把下列示例中的根目錄調整成為子目錄 (例如用 RewriteBase /name-of-your-subfolder/ 替換掉 RewriteBase/)。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
除了 mod_rewrite,你也可以使用 FallbackResource (opens new window)。
location / {
try_files $uri $uri/ /index.html;
}
const http=require('http')
const fs=require('fs')
const httpPort=80
http.createServer((req, res)=> {
fs.readFile('index.html', 'utf-8', (err, content)=> {
if (err) {
console.log('We cannot open "index.html" file.')
}
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8'
})
res.end(content)
})
}).listen(httpPort, ()=> {
console.log('Server listening on: http://localhost:%s', httpPort)
})
對于Node.js/Express,請考慮使用 connect-history-api-fallback 中間件 (opens new window)。
1. 安裝 IIS UrlRewrite(opens new window)
2. 在你的網站根目錄中創建一個 web.config 文件,內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Handle History Mode and custom 404/500" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
rewrite {
regexp .*
to {path} /
}
在你的 firebase.json 中加入:
{
"hosting": {
"public": "dist",
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}
給個警告,因為這么做以后,你的服務器就不再返回 404 錯誤頁面,因為對于所有路徑都會返回
index.html 文件。為了避免這種情況,你應該在 Vue 應用里面覆蓋所有的路由情況,然后再給出一個 404 頁面。
const router=new VueRouter({
mode: 'history',
routes: [
{ path: '*', component: NotFoundComponent }
]
})
或者,如果你使用 Node.js 服務器,你可以用服務端路由匹配到來的 URL,并在沒有匹配到路由的時候返回 404,以實現回退。
點擊關注,第一時間了解華為云新鮮技術~華為云博客_大數據博客_AI博客_云計算博客_開發者中心-華為云
*請認真填寫需求信息,我們會在24小時內與您取得聯系。