blog icon indicating copy to clipboard operation
blog copied to clipboard

vue 路由配置 history 模式

Open huangshuwei opened this issue 7 years ago • 2 comments
trafficstars

前言

这里记录下 vue 路由配置成 history 模式的过程。

路由 hash 模式

vue 路由默认是 hash 模式。使用这种模式url 地址上模式会有一个路由标识 ‘#’,乍一看以为是锚点。 这种模式存在以下缺点:

1、本身与锚点冲突,导致页面需要用到锚点定位时比较困难 2、路由切换滚动行为还原困难,当然可以通过其他方式实现,参考这里 3、不利于 SEO 4、url 丑(哈哈,别当真)

既然用hash 模式不爽,那我们就改成 history 模式。

vue 路由配置修改

就是在这里改下

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

这时候我们重启将项目运行起来,不错,就是这个效果。对比下url地址 hash 模式: 协议://域名:端口/index.html#/home history 模式: 协议://域名:端口/home

会看到将 index.html# 省略掉了。

webpack 热启动配置 history 模式

我们通过webpack 热启动(webpack-dev-server)路由切换正常访问,但是当刷新页面,或者点击浏览器回退的时候提示找不到了,这是因为使用了 history 模式,webpack 热启动也需要对应的配置。 怎么配置呢,有两种方式,也可参考webpack官网配置

方式1 通过命令行的方式,形如 webpack-dev-server --history-api-fallback,不过一般都是放到 'scripts'节点下,如:

// package.json
 "scripts": {
    "dev": "webpack-dev-server  --env.dev --history-api-fallback"
  }

方式2 在 webpack 配置文件的devServer配置:

// webpack.config.js
devServer:{
  ...
 historyApiFallback: true
}

如果是使用了 webpack 的 ‘webpack-dev-middleware’,你可能需要配合connect-history-api-fallback插件达到页面刷新回退不报错的目的,这里不多说了(因为我用的不是这种方式😂)

webpack history 模式发布

通过history 模式发布后,也是刷新以及页面回退都会出现找不到的问题,这时候需要对应的站点服务器处理了。

IIS 服务环境安装

因为我们的站点放到IIS 上的,下面以IIS 环境为例。

其他平台 history 模式的设置官网有说明

1、安装 IIS UrlRewrite

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>

这里配置的目的就是把包含 .*的路径名称 替换成 '/'。

这时候再去打开部署好的站点,无论是页面刷新还是回退操作一切正常。

注意:单页应用的入口命名一定要是 index.html 否则页面刷新后会报错

Q&A(自问自答)

  • 单页应用的入口文件必须是index.html 吗? 如果入口文件不是index.html, 调试模式(webpack-dev-server) , 刷新会报错,回退可以。 发布后部署在iis 上也是一样的问题,不能刷新。所以入口文件必须是index.html

  • 单页应用与多页应用通过webpack 统一管理的项目会有问题吗? 我已经在项目中使用过,history 模式 只会作用在单页应用上,对多页应用无影响,访问多页应用依旧通过 ~*.html 方式

  • 我用 nginx 作为负载均衡,还需 nginx 配置后端url 重写规则吗? 不需要,只有nginx 作为 http 服务器的时候才需要。nginx 作为负载均衡时只要每个站点配置即可。

待解决的问题

  • 开启 history 模式后层级目录没了? 资源路径改为绝对路径

参考

https://docs.microsoft.com/zh-cn/iis/extensions/url-rewrite-module/using-the-url-rewrite-module

--完?--

huangshuwei avatar Dec 05 '17 08:12 huangshuwei

不错!清晰明了

MrErHu avatar May 09 '19 02:05 MrErHu

我改了两处,一个是devserver的historyApiFallback,还有一个就是mode从hash改成了history,为什么页面没有加载出来呢,直接白屏了

hanguangpeng avatar Sep 23 '19 02:09 hanguangpeng