1. 背景
團隊的前端使用 React + React Router 開發單頁應用(SPA),特別影響用戶體驗的一個痛點是:
- 瀏覽器刷新當前頁面,提示 404
- 點擊瀏覽器歷史記錄,提示 404
- 輸入 URL,提示 404
Linux + Nginx 環境前端團隊找到了解決方案,在 nginx.conf
添加如下代碼即可:
location ~ /xxx/ {
if ($request_uri ~* ^([^.]+|.*\.html)$){
proxy_pass http://$proxy_ip/xxx-lk/index.html;
}
root /opt/wwwroot/;
index /xxx/index.html;
}
location ~ /xxx-lk/ {
root /opt/wwwroot/;
index /xxx/index.html;
}
}
即將上線的項目,客戶使用 Windows 服務器,我們不得不在 IIS 完成同樣的配置……
2. 路由原理
2.1. Server side
傳統的 B/S 開發,在瀏覽器地址欄輸入 http://example.com/about
后,瀏覽器請求 example.com
服務器,服務器接收請求之后解析 URL 得到 about
,向瀏覽器發送「關于我們」頁面。
2.2. Client side
使用客戶端路由時,在瀏覽器地址欄輸入 http://example.com/about
后:
- 向服務器
example.com
發起請求,服務端路由找不到/about
,默認返回包含所需資源的頁面index.html
。 - 瀏覽器加載 React 和 React Router,路由初始化成功,將
/about
指向About us
組件(Component)。 - 瀏覽器 URL 為
http://example.com/about
,客戶端路由導航顯示About us
組件,隱藏其他組件。
2.3. React Router
React Router 是建立在 history 之上的,history 監聽瀏覽器地址欄的變化并解析 URL 轉化為 location
對象,然后 router 使用它匹配到路由,正確地渲染對應的組件。
常用的 history 有三種形式:
- browserHistory
- hashHistory
- createMemoryHistory
使用 React Router 時推薦用 Browser history,它使用瀏覽器的 History API 處理 URL,創建類似于 http://example.com/about
這樣真實的 URL。
3. 解決方案
3.1. IIS
web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="React-Router" stopProcessing="true">
<match url="^xxx/(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="xxx/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
3.2. Nginx
nginx.conf
location /xxx {
try_files $uri $uri/ /xxx/index.html;
}