Nginx怎么解決history模式下頁面刷新404問題

    前置知識

    • 單頁應用(spa – single page application)
      只在第一次加載頁面時,返回唯一的html頁面和它的公共靜態資源,后續的頁面跳轉都不會從服務端拿html文件。(hash和history路由實現瀏覽器url變化而不刷新頁面)

    • hash路由
      例子:www.baidu.com/#/home, 原本hash是用來結合錨點實現頁面試圖的控制,當#后面的值發生改變時不會重新請求頁面,主要通過window的onhashchange方法來實現。

    • history路由
      相比于hash路由,最直觀的變化就是路由中沒有#,通過調用window.history對象上的一系列方法來實現頁面的無刷新跳轉(pushState、replaceState)。

    history模式下,因為url改變了,此時如果手動刷新頁面,瀏覽器認為是請求一個新的頁面(發起新的Http請求),而新的頁面是不存在的(后端未配置的話),導致404。

    先簡述一下在瀏覽器上輸入IP或域名后發生的事情(有點面試題的味道了嗷????),按下回車之后,瀏覽器發出的http去請求html文件,在通過一系列的轉發和尋址解析后,被目標IP所在服務器上的80端口(默認)接收,這個時候,問題來了哈,服務器的80接口拿到Http請求后,它不知道要去返回什么,這個時候就需要nginx進行靜態資源代理,告訴服務器返回什么靜態文件

    Nginx

    對于一般的項目部署,我們需要處理nginx.conf配置文件
    該文件,需要知道的如下

    ???.... ???#?http?是指令塊,針對http網絡傳輸的一些指令配置 ???http?{ ???????#文件擴展名與文件類型映射表? ???????include?mime.types; ???????#設置客戶端與服務端請求的超時時間 ???????keepalive_timeout??65; ???????#?開啟壓縮功能,目的:提高傳輸效率,節省帶寬? ???????gzip?on ???????server?{ ??????????#監聽端口 ??????????listen???80; ??????????#服務命名,最好就是用這個服務器的域名命名 ??????????server_name?localhost; ??????????#指令塊,配置外部訪問資源和實際資源的對應關系 ??????????location?/{ ??????????????root?/usr/blog;?#表示靜態資源所在的目錄 ??????????????index??index.html?index.htm;?#訪問這個路徑對應的默認靜態資源文件或者網頁 ??????????} ???????} ???}

    location

    語法

    ???location?[=|~|~*|^~|@]?uri?{?...?}? ???location?@name?{?...?}
    • =:表示精確匹配

    • ~:表示區分大小寫正則匹配

    • ~*:表示不區分大小寫正則匹配

    • ^~:表示 URI 以某個常規字符串開頭

    • !~:表示區分大小寫正則不匹配

    • !~*:表示不區分大小寫正則不匹配

    • /:通用匹配,任何請求都會匹配到

    常用匹配規則

    ???#?將所有請求直接轉發給服務器的9090端口 ????location?=?/?{ ??????proxy_pass?http://127.0.0.1:9090/; ????} ????#?目錄匹配? ????location?^~?/static/?{? ????????root?/webroot/static/; ????}? ????#?后綴匹配? ????location?~*?.(gif|jpg|jpeg|png|css|js|ico)$?{? ????????root?/webroot/res/;? ????} ????#?將/account/開始的請求轉發給Account服務器 ????location?/account/?{ ????????proxy_pass?http://127.0.0.1:8080/ ????} ????#?將/order/開始的請求轉發給Order服務器 ????location?/order/?{ ????????proxy_pass?http://127.0.0.1:9090/ ????}

    root 與 alias

    兩者區別在于 nginx 如何解釋 location 后面的 url

    [root]語法:root path默認值:root html配置段:http、server、location、if處理結果:root 路徑+ location 路徑

    [alias]
    語法:alias path
    配置段:location
    處理結果:使用 alias 路徑替換 location 路徑

    ???#?返回/www/root/html/t/a.html的文件 ???location?^~?/t/?{? ???????root?/www/root/html/; ???}? ???#?返回/www/root/html/new_t/a.html的文件? ???#?把location后面配置的路徑丟棄掉,把當前匹配到的目錄指向到指定的目錄。? ???location?^~?/t/?{? ???????alias?/www/root/html/new_t/;? ???}

    解決刷新后出現404的問題

    由上面的知識可以知道,刷新后,瀏覽器根據當前的url去請求html文件,但是SPA只有一個html文件,所以需要在nginx.conf的對應location里配置一行代碼 try_files $uri $uri/ /index.html; 告訴nginx如果按順序檢查文件是否存在,若不存在則重定向到index.html文件

    ? 版權聲明
    THE END
    喜歡就支持一下吧
    點贊7 分享