nginx 适配react-router browserRoute 路由问题

更新日期: 2019-07-24阅读: 2.6k标签: 路由

本文环境比较复杂,首先两层nginx转发,并且访问路径也不是根路径。加上对nginx一知半解,各路搜索一看,全程懵逼。最终没有一个能用的。最后还是靠同事帮助,文档大法结束加班。本文知识点:location优先级,nginx资源文件寻找方式,rewrite 重定向问题。


location 优先级

  • = 开头表示精确匹配
  • ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。以xx开头
  • ~ 开头表示区分大小写的正则匹配                     以xx结尾
  • ~* 开头表示不区分大小写的正则匹配                以xx结尾
  • !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
  • / 通用匹配,任何请求都会匹配到。


try_file 使用

当用户请求 http://localhost/example 时,这里的 $uri 就是 /example。 
try_files 会到硬盘里尝试找这个文件。如果存在名为 /$root/example(其中 $root 是项目代码安装目录)的文件,就直接把这个文件的内容发送给用户。 
显然,目录中没有叫 example 的文件。然后就看 $uri/,增加了一个 /,也就是看有没有名为 /$root/example/ 的目录。 
又找不到,就会 fall back 到 try_files 的最后一个选项 /index.php,发起一个内部 “子请求”,也就是相当于 nginx 发起一个 HTTP 请求到 http://localhost/index.php


适配react-router browserrouter配置

首先文件存放路径是子目录 /usr/local/services/app_logical_server-1.0/bin/app/screen

访问路径是 https://example.com/app/screen/


错误的nginx 配置

    server {
        listen       8080;
        root  /usr/local/services/app_logical_server-1.0/bin/app/screen;
        location ~* \.(gif|jpg|png|js|css)$ {
          root /usr/local/services/app_logical_server-1.0/bin/app/screen/;
        }
        location ^~ /app/screen {
          root   html;
          index  index.html;
          try_files $uri $uri/ /index.html;
        }

    }


错误点

错误现象是index.html可以找到,但是index.html中的js写的是相对路径,导致所有的静态资源文件也进入了第二个location,导致页面白屏。
分析如下。

1.优先级问题

首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
~* 的优先级低于 ^~所以第一个配置静态资源文件虽然写在前面,还是不会进去的。

2. server root 配置错误

解决优先级问题后,问题依然存在。原因就是这个。root 在server和location中都有,都是配置文件开始寻找的根路径,如果url是https://xxxx:8084/app/screen,location中的配置优先级高于server。首先会进入第二个location中,寻找文件,文件路径是root和域名后面的路径的拼接,例如:访问路径是 https://example.com/app/screen/umi.js,server root 为 /usr/local/services/app_logical_server-1.0/bin/app/screen。 nginx寻找文件的地址为/usr/local/services/app_logical_server-1.0/bin/app/screen/app/screen/umi.js.当然找不到,报404错误。


正确的配置

    server {
        listen       8084;
        root  /usr/local/services/app_logical_server-1.0/bin/;
        location ~* \.(gif|jpg|png|js|css)$ {
            root  /usr/local/services/app_logical_server-1.0/bin;
        }
        location ~* /app/screen {
          #try_files $uri $uri/ /usr/local/services/app_logical_server-1.0/bin/app/screen/index.html;
          root  /usr/local/services/app_logical_server-1.0/bin;
          try_files /app/screen/index.html =404;
        }
    }


不带/的url重定向问题

当前配置还有个问题,就是末尾不带斜杠时,index.html可以加载到,但是html中的资源文件写的相对路径,当url 为https://example/app/screen时,相对路径为https://example/app,以js为例,https://example/app/umi.js,所以报404错误。 解决方案为,利用location优先级,再加一个 = /app/screen 的location 。

    location = /sa/screen {
        rewrite ^([^.]*[^/])$ $1/ permanent;
        port_in_redirect off;
    }

但是到此还没结束。因为业务需要,本层nginx前面还有一层Nginx。所以301 重定向的时候,会带上端口号。导致找不到请求。port_in_redirect off; 配置可以解决此问题

最终版完美配置

server {
        listen       8084;
        root  /usr/local/services/app_logical_server-1.0/bin/;
        location = /sa/screen {
            rewrite ^([^.]*[^/])$ $1/ permanent;
            port_in_redirect off;
        }
        location ~* \.(gif|jpg|png|js|css)$ {
            root  /usr/local/services/app_logical_server-1.0/bin;
        }
        location ~* /app/screen {
          #try_files $uri $uri/ /usr/local/services/app_logical_server-1.0/bin/app/screen/index.html;
          root  /usr/local/services/app_logical_server-1.0/bin;
          try_files /app/screen/index.html =404;
        }
    }

来自:https://segmentfault.com/a/1190000020170428

链接: https://fly63.com/article/detial/4894

vue路由history模式_如何去除vue项目中的#

在使用vue-cli搭建的环境中,浏览器上URL地址中是存在#的,这是由于vue-router 默认 hash 模式,不难发现#的出现真的很丑陋。官网给出了如何使用history模式mode: history

vue路由传参主要的3种方式

vue中路由传参主要的3种方式:query方式(push时使用path来匹配)、params模式(push时使用name来匹配)、location预声明参数模式(push使用path来匹配,但是它跟params模式不同)

vue动态加载路由_实现vue动态加载路由器设置

我们的通用的后台管理系统中,我们会根据权限的粗细不同,会对每个角色每个权限每个资源进行控制。同样的我们也需要实现一个这样的功能。 这篇文章我将主要讲vue端的实现,关于后台接口我就不会涉及,当我接触的时候我们的后台接口是springcloud实现。

两种前端路由的实现方式

前后端分离开发模式,后端会把路由控制丢在前端,这几天再开发单页面小的项目,手动撸了个路由。前端路由实现有两种方法。HTML5 History API包括2个方法:history.pushState()和history.replaceState(),和1个事件:window.onpopstate。hash + location.onhashchange

vue动态路由_vue-router通过接口请求动态生成路由的实现

在后台管理系统中,一般都会采用权限管理。路由菜单数据都会保存到数据库中,在vue-router 2.2版本新增了一个router.addRoutes(routes)方法,即可用它来实现动态路由了

HTML5 History 模式

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

vue router 路由鉴权(非动态路由)

原本想用动态路由的思路去做,按权限加载对应路由表,但是由于权限可以交叉(比如一个人可以同时是主题管理员和数据服务管理员),导致权限路由表还是得去做判断组合。于是放弃了这个思路,索性就在beforeEach里直接判断了。

vue中路由按需加载的几种方式

使用vue-cli构建项目后,我们会在Router文件夹下面的index.js里面引入相关的路由组件,webpack在打包的时候会把整个路由打包成一个js文件,如果页面一多,会导致这个文件非常大,加载缓慢

vue-router 中参数传递(params,query)

query和params的区别,query相当于get请求,在页面跳转的时候,可以在地址栏看到请求参数,然而params则相当于post请求,参数不会在地址栏中显示。

Node.js的路由

当服务端接收到HTTP请求时,可以通过onRequest() 获取到url, pathname,query,及paramParams参数;为了解析这些数据需要使用url和querystring模块

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!