尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Vue Router 2 的 HTML5 History 模式:从配置到服务器回退的完整实战指南

Vue Router 2 的 HTML5 History 模式:从配置到服务器回退的完整实战指南 前端路由【免费下载链接】vue-router The official router for Vue 2项目地址https://gitcode.com/gh_mirrors/vu/vue-router点击查看免费下载导读vue-router默认使用 Hash 模式URL 带#而HTML5 History 模式history mode能让你获得形如http://oursite.com/user/id的正常URL为 Vue 2 应用提供更干净、更友好的地址形态。本指南以仓库 docs-gitbook/de/essentials/history-mode.md 的完整内容为主线结合 src/router.js、src/history/html5.js 等源码与 examples 下的真实示例带你完成从开启 history 模式到为 Apache、nginx、Node.js、IIS、Caddy、Firebase 等主流服务器配置 catch-all 回退再到在 Vue 应用内兜底 404 页面的全流程并理解其底层原理与base、fallback等配置项的取舍。为什么需要 history 模式Hash 模式的局限vue-router的默认模式是Hash 模式它利用 URL 中的#hash来模拟完整的 URL从而在 URL 变化时不触发页面重新加载。从源码角度看Hash 模式由 src/history/hash.js 中的HashHistory实现它监听popstate或在不支持pushState时退化为hashchange事件通过读写window.location.hash完成导航。Hash 模式最大的问题是 URL 形态不美观http://oursite.com/#/user/id。对用户和搜索引擎都不够友好。而history 模式直接使用 HTML5 的history.pushStateAPI 实现无刷新导航从而去掉#号。从 src/router.js 可以看到模式选择的默认逻辑let mode options.mode || hash this.fallback mode history !supportsPushState options.fallback ! false if (this.fallback) { mode hash } if (!inBrowser) { mode abstract } this.mode mode即默认hash当显式指定history但浏览器不支持pushState且未关闭fallback时自动降级回hash在非浏览器环境如 Node.js下强制使用abstract模式。开启 history 模式只需在创建VueRouter实例时设置mode: historyconst router new VueRouter({ mode: history, routes: [...] })启用后URL 会呈现正常的路径形态例如http://oursite.com/user/id。整个仓库的 examples 目录下几乎所有示例都采用了mode: history例如 examples/basic/app.js、examples/named-routes/app.js、examples/scroll-behavior/app.js可以直接打开验证效果。底层发生了什么HTML5History 的导航链路开启 history 模式后VueRouter会实例化 src/history/html5.js 中的HTML5History类见 src/router.js 的switch分支。其核心导航链路如下push(location)先执行transitionTo完成路由守卫与组件解析成功后调用pushState(cleanPath(this.base route.fullPath))把新 URL 写入地址栏src/history/html5.jsreplace(location)逻辑与push相同但使用replaceState不产生新的历史记录src/history/html5.jssetupListeners()注册window.addEventListener(popstate, ...)监听浏览器前进/后退事件并处理滚动行为src/history/html5.jsgo(n)直接透传window.history.go(n)src/history/html5.js。pushState/replaceState的底层实现在 src/util/push-state.js它会在调用前保存滚动位置并给 history state 打上key以便恢复滚动值得注意的是它对 Safari 做了保护——Safari 限制 100 次pushState调用DOM Exception 18因此用try...catch包裹出错时回退到window.location.assign/window.location.replace。配置项mode / base / fallback在 docs/api/README.md 中与 history 模式直接相关的三个配置项为配置项类型默认值说明modestringhash浏览器/abstractNode.js可选hash \| history \| abstract。history需要 HTML5 History API 和服务器配置支持abstract适用于所有 JS 环境非浏览器环境下会被自动强制启用basestring/应用的基础 URL。例如整个 SPA 部署在/app/下时base应设为/app/fallbackbooleantrue当mode为history但浏览器不支持history.pushState时是否回退到hash模式。设为false时在 IE9 中每次router-link导航都会变成整页刷新——这对服务端渲染SSR场景很有用因为 hash 模式 URL 无法与 SSR 配合base的规范化逻辑在 src/history/base.js 的normalizeBase中若未显式指定会优先读取 HTML 文档中的base标签的href会保证以/开头并去除末尾斜杠。HTML5History.getLocation在解析当前路径时也会结合base正确裁剪前缀见 src/history/html5.js。部署到子目录时英文版官方文档特别提示见 docs/guide/essentials/history-mode.md若应用部署在子文件夹而非根目录应使用 Vue CLI 的publicPath选项以及路由器的base属性同时把下文服务器配置中的根路径如RewriteBase /替换为子文件夹路径如RewriteBase /name-of-your-subfolder/。问题所在直接访问 URL 会得到 404History 模式有一个绕不开的问题应用本质上是运行在浏览器端的单页应用SPA如果服务器没有做相应配置用户直接在地址栏访问http://oursite.com/user/id时服务器会在这个路径下找不到任何静态文件从而返回404。解决办法是在服务器配置中加入一条catch-all 回退规则——只要 URL 不匹配任何静态文件或目录就统一把应用所在的index.html返回给浏览器由前端路由接管后续渲染。下面给出各主流服务器的配置方案。各服务器 catch-all 回退配置以下示例均假设应用部署在根目录。Apache使用mod_rewrite模块IfModule mod_negotiation.c Options -MultiViews /IfModule IfModule mod_rewrite.c RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L] /IfModule规则含义拆解Options -MultiViews关闭内容协商避免 Apache 自动把/user/id映射到index.html之外的资源RewriteRule ^index\.html$ - [L]对index.html本身的请求直接放行不再重写RewriteCond %{REQUEST_FILENAME} !-f请求的文件不存在RewriteCond %{REQUEST_FILENAME} !-d请求的目录不存在RewriteRule . /index.html [L]其余所有请求一律重写到/index.html。除mod_rewrite外也可以使用 Apache 的FallbackResource指令mod_dir模块实现同样的效果。nginx在server块中location / { try_files $uri $uri/ /index.html; }try_files依次尝试请求的路径是否存在对应文件$uri→ 是否是目录$uri/→ 都不满足则回退到/index.html。Node.js 原生 HTTP 服务器不依赖任何框架用 Node 原生http模块实现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; charsetutf-8 }) res.end(content) }) }).listen(httpPort, () { console.log(Server listening on: http://localhost:%s, httpPort) })这段代码对所有请求都直接返回index.html适合纯前端 SPA 场景若有静态资源需要先判断请求路径再做静态文件服务。Node.js Express对于 Node.js/Express 项目官方推荐使用connect-history-api-fallback中间件。该中间件专门解决 history 模式的回退问题会拦截所有不匹配静态资源的请求并转发到index.html。仓库自带的示例服务器 examples/server.js 展示了 Express 下的完整做法它用express-urlrewrite把每个示例目录下的/*请求重写到对应目录的index.html再用express.static托管静态文件。这正是 history 模式 Express 的标准工作方式运行node examples/server.js后即可在http://localhost:8080下访问各个 history 模式示例。IISInternet Information Services安装 IIS UrlRewrite 扩展在站点根目录创建web.config内容如下?xml version1.0 encodingUTF-8? configuration system.webServer rewrite rules rule nameHandle History Mode and custom 404/500 stopProcessingtrue match url(.*) / conditions logicalGroupingMatchAll add input{REQUEST_FILENAME} matchTypeIsFile negatetrue / add input{REQUEST_FILENAME} matchTypeIsDirectory negatetrue / /conditions action typeRewrite url/ / /rule /rules /rewrite /system.webServer /configuration规则逻辑与 Apache 版一致请求既不是真实文件IsFile取反也不是真实目录IsDirectory取反时重写到站点根目录/。CaddyCaddy v2try_files {path} /Caddy v1rewrite { regexp .* to {path} / }Firebase Hosting在firebase.json中添加 rewrite 规则{ hosting: { public: dist, rewrites: [ { source: **, destination: /index.html } ] } }source: **匹配所有路径统一重写到/index.html。重要警告服务器不再返回 404 了引入 catch-all 回退后有一个副作用服务器将不再对任何不存在的路径返回 404因为所有未匹配路径最终都会拿到index.html。此时404 页面必须由 Vue 应用自己处理。在 Vue 应用内兜底 404 页面在路由配置中添加一条 catch-all 路由来渲染 404 组件。Vue Router 2 支持两种写法方式一文档写法const router new VueRouter({ mode: history, routes: [ { path: *, component: NotFoundComponent } ] })方式二带名称与通配捕获推荐const router new VueRouter({ mode: history, routes: [ { path: /:catchAll(.*), component: NotFoundComponent, name: NotFound } ] })第二种写法基于path-to-regexp的命名通配参数/:catchAll(.*)可以捕获任意剩余路径并给路由命名name: NotFound便于在代码中通过router.push({ name: NotFound })编程式跳转。替代方案服务端路由参与 404 判断如果你使用 Node.js 服务器也可以在服务端完成更精细的 404 判断让服务端路由系统对进来的 URL 进行匹配只有当 URL 对应 Vue 应用已注册的路由时才回退到index.html否则返回真正的 404。这也正是服务端渲染SSR方案所采用的做法——可进一步参考 Vue 的 SSR 文档了解完整实现。快速验证跑起仓库里的 history 模式示例仓库 examples 目录下的所有示例均已开启mode: history可以按以下步骤快速验证安装依赖使用 yarn 或 npmyarn install启动示例服务器见 examples/server.js默认监听http://localhost:8080node examples/server.js浏览器访问各示例例如http://localhost:8080/basic/、http://localhost:8080/named-routes/直接刷新或手工输入子路径如/basic/foo确认服务器回退规则让 SPA 正常接管。注意示例服务器通过express-urlrewrite将每个示例目录下的子路径重写到对应index.htmlexamples/server.js这正对应上文服务器 catch-all 回退在生产环境中的部署形态。小结Hash 模式是默认模式URL 带#、无需服务器配置history 模式通过history.pushState提供正常URL但必须配合服务器 catch-all 回退否则直接访问子路径会 404。主流服务器Apache / nginx / Node.js / Express / IIS / Caddy / Firebase都有成熟的回退配置方案本文已给出可直接使用的完整配置。catch-all 回退会让服务器失去 404 能力因此必须在 Vue 应用内用path: *或path: /:catchAll(.*)定义 404 页面Node.js 服务端还可以用服务端路由做更精确的 404 判断。与 history 模式配套的配置项mode、base、fallback分别控制模式选择、子目录部署和旧浏览器降级行为源码层面的支撑可查阅 src/router.js、src/history/html5.js、src/util/push-state.js 与 docs/api/README.md。赞分享前端路由【免费下载链接】vue-router The official router for Vue 2项目地址https://gitcode.com/gh_mirrors/vu/vue-router点击查看免费下载相关推荐vue-router HTML5 History 模式实战指南原理、服务端配置与 404 兜底方案vue router HTML5 History 模式实战指南原理、服务端配置与 404 兜底方案 vue router 默认使用 hash 模式通过 UR前端路由electerm 使用指南SSH、桌面与文件传输一个窗口全搞定electerm 使用指南SSH、桌面与文件传输一个窗口全搞定 这篇 electerm 使用教程以先跑起来的思路展开讲清安装、首次配置和连上第一台 S前端路由深度解析Beads基于Dolt的分布式AI代理任务跟踪架构深度解析Beads基于Dolt的分布式AI代理任务跟踪架构 Beads是一个为编码代理提供结构化记忆升级的开源项目通过版本控制的依赖感知图取代传统的Mark前端路由创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表