nginx配置单页应用之路由匹配以及404页面

我们希望能够尽我们所能,来让这个世界变的更简单,如果你想了解我们,请点击这里


最近在使用vue+vue-router+webpack去构建了一套前端系统,把系统在本地调试完成之后,发布到阿里云服务器上,使用nginx去做反向代理的时候,遇到了3个问题。这里把这些问题整理一下,希望能够帮助到遇到了同样问题的人。


1、域名后面多了 /#/ 标志

在访问网站的时候还是比较正常的,但是在域名后面多了一个 # 井字号标志,这可不是我想要的,调研之后发现,这个 # 井字号标志 标志其实与nginx的配置无关,问题出在 vuew-router上面 。

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

这就是这个问题的解决方案了,我们在定义vue-router的时候,如果不想要那个不好看的hash,我们需要给他指定一个 history模式。 就像这样

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

官网上的原文地址

不过这样的写法,在你通过vue-router去跳转到其他的页面的时候,很快就遇到了第二个问题。那就是

2、路由跳转返回404页面

官网在告诉我们使用history模式的时候 也提到了这个问题。

当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!

不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。

所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

好吧,,,让我们按照官网的说法,来配置一下我们的nginx。

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

我们需要使用nginx的 try_files 功能,来去截取我们所有的url请求,把他们指向到我们单页应用中仅有的一个html文件。
这样我们就可以发现,无论我们在url上输入什么,只要域名没错,那么都会跳转到我们的index.html文件了 。
等等。。。。 我们做了什么 。。 都跳转过去?那我们的404页面呢??
这里写图片描述
下面就是我们需要做的第三个事情了,寻找我们的404页面。

3、匹配404页面

好吧。让我们重新审视一下我们的nginx配置。

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

我们先去仔细的认识 try_files

try_files指令
语法:try_files file ... uri 或 try_files file ... = code
默认值:无
作用域:server location

其作用是按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有的文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。

这就很明确了,我们的这种写法try_files $uri $uri/ /index.html;就会导致所有找不到的url都会跳转到index.html文件。

那么这个问题怎么处理呢?
我们需要兼顾单页应用中url的配置,又需要兼顾到我们404页面的展示。
思前想后,我觉得还是if语法会比较合适。

location / {
            if ($uri = /routerName) {
                rewrite .* /index.html break;
            }
            root   /sunday/website/dist/;
            index  index.html index.htm;
        }

这段配置表示为:如果我们检测到了url匹配了我们定义的路由名称,我们就会让他跳转到index.html,并且默认的html为index.html。 路径的根路径使在/sunday/website/dist/下面。(ps:个人建议把root /sunday/website/dist/;放入server下面,不要在每个location下都写入一遍)。

最后附上nginx的匹配规则

语法规则: location [=|~|~*|^~] /uri/ { … }

= 开头表示精确匹配

^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。

~ 开头表示区分大小写的正则匹配

~* 开头表示不区分大小写的正则匹配

!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则

/ 通用匹配,任何请求都会匹配到。

多个location配置的情况下匹配顺序为(参考资料而来,还未实际验证,试试就知道了,不必拘泥,仅供参考):

首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

欢迎大家评论,如果转载请标明出处。如果能够对大家有所帮助,那么我会感到非常高兴。

猜你喜欢

转载自blog.csdn.net/u011068996/article/details/80665775