问题出现的环境背景
vue项目打包生成dist文件夹,将dist放到本机的nginx下运行,打开页面,正常点击菜单时,可以打开页面,除了主页,其他路由页面使用浏览器刷新或者复制url地址打开时,会出现页面404的情况。nginx的配置如下:

server {
		# ...其他部分省略...
        listen       8081;
        server_name  localhost;
        location / {
            root   xxx/dist; # xxx 表示vue项目路径
            index  index.html index.htm;
        }
        # ...其他部分省略...
}

问题定位

由于vue项目中router使用的mode为history:

nginx哈希路由映射browser路由 nginx hash路由_vue.js

分析:

  1. vue-router默认是hash模式,使用urlhash来模拟一个完整的url,当url改变的时候页面不会重新加载,hash模式路由中会携带#
  2. history模式的路由,url携带#history模式的路由需要后台配置的支持,否则只有在项目主页(也就是根路由下,eg:http://localhost:8081/)时能正常访问,在其他路由页面(eg:http://localhost:8081/filter-list)刷新或者直接复制地址打开时就会出现404的情况

    因为在history模式下,只是动态的通过js来操作window.history来改变浏览器的地址,并没有发起http请求,但是当直接在浏览器中输入地址时,就一定要对服务器发起http请求,但是这个目标不存在服务器上,所以返回404
    但是在开发环境使用history模式又不会出现问题,是因为开发时用的是node为服务器,dev环境中已经配置好了

那么在nginx启动的情况下如何去解决404的问题呢?(参考vue-router官方给出的解决办法)

  • 在nginx的配置文件(nginx.conf文件)中添加try_files $uri $uri/ /index.html
  • nginx哈希路由映射browser路由 nginx hash路由_前端_02


  • 重启打开页面刷新检查是否有效,如果前端路由部分代码没有问题,一般情况下,就能正常刷新了
  • 如果此时率先你页面显示空白,不是显示404了,此时需要去检查一下代码是否出现了问题

    当我修改了路由中自定义的prefixPath之后,就能正常刷新页面了
    ----------------------------------------------------------------------------------------

简单解释try_files指令:

(可参考文章对该指令的解释)

  • try_files $uri $uri/ /index.html:它的作用是按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有的文件或文件夹都找不到,会进行一个内部重定向走到最后一个参数。
  • 需要注意的是,只有最后一个参数能引起一个内部重定向,之前的参数只能设置内部的uri的指向。最后一个参数是回退uri且必须存在,否则会引起内部500的错误
  • 举例:假如root是这样定义的 root xxx/dist; # xxx 表示vue项目路径,浏览器中的地址为http://localhost:8084/data-list 那么就是寻找xxx/dist/$uri,其中$uri就是URL中的路径,即/data-list。所以最终访问的就是xxx/dist/data-list,访问不到data-list这个文件就继续查找data-list/这个文件夹,都不存在,就返回最后一个参数index.html,也就是xxx/dist/index.html。