最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue history模式刷新頁面404問題及解決

 更新時(shí)間:2024年12月09日 16:26:08   作者:梅塢茶坊  
文章介紹了Vue單頁應(yīng)用中出現(xiàn)404錯(cuò)誤的原因,以及如何通過配置Nginx和使用Vue Router的hash模式來解決這個(gè)問題,同時(shí),文章還簡要解釋了單頁應(yīng)用的概念及其優(yōu)點(diǎn)和缺點(diǎn),并討論了Router的實(shí)現(xiàn)方式

為什么會出現(xiàn)404

我們先來看一下我們給到后端的dist文件

可以看到dist下只有一個(gè) index.html 文件及一些靜態(tài)資源,這個(gè)是因?yàn)?code>Vue是單頁應(yīng)用(SPA),只有一個(gè)index.html作為入口文件,其它的路由都是通過JS來進(jìn)行跳轉(zhuǎn)

接著我們再來分析一下后端 nginx 的配置

server {
  // 監(jiān)聽80端口
  listen 80;
  // 定義你的站點(diǎn)名稱
  server_name website.com;
  // 根據(jù)請求 URI 設(shè)置配置
  location / {
      // 站點(diǎn)根目錄,這里為 vue 構(gòu)建出來的 dist 目錄
      root   /www/dist;
      // 站點(diǎn)初始頁為index.html 或 index.htm
      index  index.html index.htm;
  }
}

我們現(xiàn)在可以根據(jù) nginx 配置得出,當(dāng)我們在地址欄輸入 website.com 時(shí),這時(shí)會打開我們 dist 目錄下的 index.html 文件,然后我們在跳轉(zhuǎn)路由進(jìn)入到 website.com/login

關(guān)鍵在這里,當(dāng)我們在 website.com/login 頁執(zhí)行刷新操作,nginx location 是沒有相關(guān)配置的,所以就會出現(xiàn) 404 的情況

為什么hash模式下沒有問題

router hash 模式我們都知道是用符號#表示的,如 website.com/#/login, hash 的值為 #/login

它的特點(diǎn)在于:hash 雖然出現(xiàn)在 URL 中,但不會被包括在 HTTP 請求中,對服務(wù)端完全沒有影響,因此改變 hash 不會重新加載頁面

hash 模式下,僅 hash 符號之前的內(nèi)容會被包含在請求中,如 website.com/#/login 只有 website.com 會被包含在請求中 ,因此對于服務(wù)端來說,即使沒有配置location,也不會返回404錯(cuò)誤

單頁應(yīng)用(SPA)概念

我們前面有提到單頁應(yīng)用,那什么是單頁應(yīng)用呢?

單頁應(yīng)用

單頁應(yīng)用(single-page application),縮寫SPA 是一種網(wǎng)絡(luò)應(yīng)用程序或網(wǎng)站的模型,它通過動(dòng)態(tài)重寫當(dāng)前頁面來與用戶交互,而非傳統(tǒng)的從服務(wù)器重新加載整個(gè)新頁面。

這種方法避免了頁面之間切換打斷用戶體驗(yàn),使應(yīng)用程序更像一個(gè)桌面應(yīng)用程序。在單頁應(yīng)用中,所有必要的代碼(HTML、JavaScript和CSS)都通過單個(gè)頁面的加載而檢索,或者根據(jù)需要(通常是為響應(yīng)用戶操作)動(dòng)態(tài)裝載適當(dāng)?shù)馁Y源并添加到頁面。

盡管可以用位置散列或HTML5歷史API來提供應(yīng)用程序中單獨(dú)邏輯頁面的感知和導(dǎo)航能力,但頁面在過程中的任何時(shí)間點(diǎn)都不會重新加載,也不會將控制轉(zhuǎn)移到其他頁面

大白話來講:

一個(gè)杯子,早上裝的牛奶,中午裝的是開水,晚上裝的是茶,我們可以發(fā)現(xiàn),變的始終是內(nèi)容,而容器還是那個(gè)容器

當(dāng)然,每種技術(shù)都有其利弊,單頁應(yīng)用也是如此

利:

  1. 無刷新體驗(yàn),這個(gè)應(yīng)該是最顯著的有點(diǎn),由于路由分發(fā)直接在瀏覽器端完成,頁面是不刷新,對用戶的響應(yīng)非常及時(shí),因此提升了用戶體驗(yàn)
  2. 完全的前端組件化,前端開發(fā)不再以頁面為單位,更多地采用組件化的思想,代碼結(jié)構(gòu)和組織方式更加規(guī)范化,便于修改和調(diào)整

弊:

  1. 首屏較長,要在一個(gè)頁面上為用戶提供產(chǎn)品的所有功能,在這個(gè)頁面加載的時(shí)候,首先要加載大量的靜態(tài)資源,這個(gè)加載時(shí)間相對比較長
  2. 不利于 SEO,單頁頁面,數(shù)據(jù)在前端渲染,就意味著沒有 SEO,或者需要使用變通的方案

Router的實(shí)現(xiàn)

為了讓大家加深大家對 Router 的理解,這里我們實(shí)現(xiàn)一個(gè)最簡潔的 Router

  • hash 模式

核心通過監(jiān)聽url中的hash來進(jìn)行路由跳轉(zhuǎn)

// 定義 Router
class Router {
    constructor () {
        this.routes = {}; // 存放路由path及callback
        this.currentUrl = '';
        
        // 監(jiān)聽路由change調(diào)用相對應(yīng)的路由回調(diào)
        window.addEventListener('load', this.refresh, false);
        window.addEventListener('hashchange', this.refresh, false);
    }
    
    route(path, callback){
        this.routes[path] = callback;
    }
    
    push(path) {
        this.routes[path] && this.routes[path]()
    }
}

// 使用 router
window.miniRouter = new Router();
miniRouter.route('/', () => console.log('page1'))
miniRouter.route('/page2', () => console.log('page2'))

miniRouter.push('/') // page1
miniRouter.push('/page2') // page2
  • history 模式

history 模式核心借用 HTML5 history api,api 提供了豐富的 router 相關(guān)屬性

先了解一個(gè)幾個(gè)相關(guān)的api

  • history.pushState 瀏覽器歷史紀(jì)錄添加記錄
  • history.replaceState 修改瀏覽器歷史紀(jì)錄中當(dāng)前紀(jì)錄
  • history.popState 當(dāng) history 發(fā)生變化時(shí)觸發(fā)
// 定義 Router
class Router {
    constructor () {
        this.routes = {};
        this.listerPopState()
    }
    
    init(path) {
        history.replaceState({path: path}, null, path);
        this.routes[path] && this.routes[path]();
    }
    
    route(path, callback){
        this.routes[path] = callback;
    }
    
    push(path) {
        history.pushState({path: path}, null, path);
        this.routes[path] && this.routes[path]();
    }
    
    listerPopState () {
        window.addEventListener('popstate' , e => {
            const path = e.state && e.state.path;
            this.routers[path] && this.routers[path]()
        })
    }
}

// 使用 Router

window.miniRouter = new Router();
miniRouter.route('/', ()=> console.log('page1'))
miniRouter.route('/page2', ()=> console.log('page2'))

// 跳轉(zhuǎn)
miniRouter.push('/page2')  // page2

解決404

看到這里我相信大部分同學(xué)都能想到怎么解決問題了,

產(chǎn)生問題的本質(zhì)是因?yàn)槲覀兊穆酚墒峭ㄟ^JS來執(zhí)行視圖切換的,

當(dāng)我們進(jìn)入到子路由時(shí)刷新頁面,web容器沒有相對應(yīng)的頁面此時(shí)會出現(xiàn)404

所以我們只需要配置將任意頁面都重定向到 index.html,把路由交由前端處理

還是以 nginx 為例,更多版本的大家可以前往https://router.vuejs.org/zh/guide/essentials/history-mode.html 查看

location / {
  try_files $uri $uri/ /index.html;
}

這里有一個(gè)小細(xì)節(jié),如果出現(xiàn)真的 404 頁面了呢?比如 website.com/notfound

因?yàn)檫@么做以后,你的服務(wù)器就不再返回 404 錯(cuò)誤頁面,因?yàn)閷τ谒新窂蕉紩祷?index.html 文件。為了避免這種情況,你應(yīng)該在 Vue 應(yīng)用里面覆蓋所有的路由情況,然后在給出一個(gè) 404 頁面

const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: '*', component: NotFoundComponent }
  ]
})

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue3?reactive響應(yīng)式依賴收集派發(fā)更新原理解析

    vue3?reactive響應(yīng)式依賴收集派發(fā)更新原理解析

    這篇文章主要為大家介紹了vue3響應(yīng)式reactive依賴收集派發(fā)更新原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 在uniapp中實(shí)現(xiàn)圖形驗(yàn)證碼的詳細(xì)步驟

    在uniapp中實(shí)現(xiàn)圖形驗(yàn)證碼的詳細(xì)步驟

    圖形驗(yàn)證碼是一種常見的安全措施,用于防止自動(dòng)化軟件(機(jī)器人)濫用網(wǎng)站資源,如自動(dòng)提交表單,這篇文章主要介紹了在uniapp中實(shí)現(xiàn)圖形驗(yàn)證碼的詳細(xì)步驟,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-11-11
  • vue3中的setup()函數(shù)基本使用詳解

    vue3中的setup()函數(shù)基本使用詳解

    在 Vue3 中,setup 函數(shù)是一個(gè)新引入的概念,它代替了之前版本中的 data、computed、methods 等選項(xiàng),用于設(shè)置組件的初始狀態(tài)和邏輯,本文將主要介紹Setup的基本用法和少量原理,感興趣的朋友一起看看吧
    2024-02-02
  • 前端面試之vue2和vue3的區(qū)別有哪些

    前端面試之vue2和vue3的區(qū)別有哪些

    這篇文章主要為大家介紹了前端面試之vue2和vue3的區(qū)別有哪些,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • Vue中的事件處理詳情

    Vue中的事件處理詳情

    這篇文章主要介紹了Vue中的事件處理詳情,文章通過給按鈕綁定一個(gè)?click?事件展開詳細(xì)內(nèi)容介紹,需要的小伙伴可以參考一下
    2022-05-05
  • Vue的自定義事件之組件通信工具詳解

    Vue的自定義事件之組件通信工具詳解

    這篇文章主要介紹了Vue的自定義事件之組件通信工具詳解,Vue的自定義事件(Custom Events)是一種強(qiáng)大的工具,用于實(shí)現(xiàn)組件之間的通信和數(shù)據(jù)傳遞,本文將深入探討什么是Vue的自定義事件,以及如何自定義和使用它們,需要的朋友可以參考下
    2023-10-10
  • 詳解vue中v-for和v-if一起使用的替代方法template

    詳解vue中v-for和v-if一起使用的替代方法template

    這篇文章主要介紹了vue中v-for和v-if一起使用的替代方法template,使用的版本是vue?2.9.6和element-ui:?2.15.6,通過實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • electron + vue項(xiàng)目實(shí)現(xiàn)打印小票功能及實(shí)現(xiàn)代碼

    electron + vue項(xiàng)目實(shí)現(xiàn)打印小票功能及實(shí)現(xiàn)代碼

    這篇文章主要介紹了electron + vue項(xiàng)目實(shí)現(xiàn)打印小票功能,需要的朋友可以參考下
    2018-11-11
  • 使用Vue3和p5.js實(shí)現(xiàn)交互式圖像動(dòng)畫

    使用Vue3和p5.js實(shí)現(xiàn)交互式圖像動(dòng)畫

    這篇文章主要介紹了如何用Vue3和p5.js打造一個(gè)交互式圖像動(dòng)畫,文中給出了詳細(xì)的代碼示例,本代碼適用于需要在網(wǎng)頁中實(shí)現(xiàn)圖像滑動(dòng)效果的場景,例如圖片瀏覽、相冊展示等,感興趣的小伙伴跟著小編一起來看看吧
    2024-06-06
  • Vue.js每天必學(xué)之?dāng)?shù)據(jù)雙向綁定

    Vue.js每天必學(xué)之?dāng)?shù)據(jù)雙向綁定

    Vue.js每天必學(xué)之?dāng)?shù)據(jù)雙向綁定,如何進(jìn)行綁定,如何進(jìn)行數(shù)據(jù)雙向綁定,感興趣的小伙伴們可以參考一下
    2016-09-09

最新評論

榆树市| 昔阳县| 洛浦县| 巩留县| 江口县| 丹江口市| 怀集县| 深水埗区| 宣威市| 公安县| 永登县| 阳原县| 交口县| 高雄市| 延寿县| 朔州市| 克拉玛依市| 伊吾县| 桂林市| 宣汉县| 永修县| 博白县| 阿城市| 江油市| 乌苏市| 华池县| 宽城| 浦县| 开远市| 齐河县| 高青县| 海盐县| 历史| 沙河市| 前郭尔| 开封县| 繁峙县| 砀山县| 甘谷县| 嘉荫县| 焦作市|