V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
orzorzorzorz
V2EX  ›  NGINX

如何绕开 browser router 中不存在路由?

  •  
  •   orzorzorzorz ·
    orzyyyy · 2019-12-14 21:27:46 +08:00 · 3437 次点击
    这是一个创建于 1565 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    Angular 的单页应用中因为有用到锚点,所以只能用 browser router。假设目标地址为 app.com/target1。

    问题

    在访问 app.com/target1 时,路由跳转到 app.com/target1/target2, 刷新页面后 404。

    相关配置如下:

    server {
      listen 4300;
      server_name business;
    
      location / {
        try_files $uri $uri/ /index.html;
        root tempPath/dist/;
      }
    }
    
    server {
      listen 80;
      server_name entry;
      root tempPath/;
    
      location ^~ /business {
        proxy_pass http://localhost:4300;
      }
    }
    
    

    尝试的解决方法

    1. 关键字搜了 browser router with nginx,看到的都是用 try_files $uri $uri/ /index.html。我试着把最后一个参数改成 app.com/target1 所在的物理路径,也就是 tempPath/dist/,错误日志会说:rewrite or internal redirection cycle while internally redirecting to "/index.html" 。后来想想,逻辑上确实是循环,此路不通。

    2. 从页面物理层面解决。就是每个路由都写个 html,但这真的很麻烦...

    希望获得帮助的点

    希望能在 1 的方向上给点建议。看上去只要在匹配到 /business 时停下来,直接转发到 html 入口就能解决了...

    7 条回复    2019-12-16 10:20:59 +08:00
    beginor
        1
    beginor  
       2019-12-15 11:36:43 +08:00 via Android
    直接在 80 端口下面 try_files 不行么,为啥还要再转一下?
    orzorzorzorz
        2
    orzorzorzorz  
    OP
       2019-12-15 12:15:57 +08:00
    @beginor 80 端口得监听很多像这样的 app,有 app.com/target1,有 app.com/target2,我希望能写得更清晰一点就转了。实际上直接在 80 try_files 报的错跟正文里的写法报的错是一样的。
    beginor
        3
    beginor  
       2019-12-15 13:45:31 +08:00 via Android
    我一般是这样写的,参考一下:
    ```
    location /app/web/ {
    alias /app/web/;
    index index.html index.htm;
    add_header Cache-Control no-cache;
    gzip_static on;
    try_files $uri /app/web/index.html;
    }
    ```
    KuroNekoFan
        4
    KuroNekoFan  
       2019-12-16 09:09:26 +08:00 via iPhone
    约定一种 url 模式,访问这种模式的 url 都 fallback 到 html 入口文件,location 跟 router 的 basename 对应起来
    最后,如果你的 js,css 什么的跟 html 在同一个 location 里,记得上面约定的 url 模式不要跟访问 js/css 的 url 模式冲突
    orzorzorzorz
        5
    orzorzorzorz  
    OP
       2019-12-16 09:53:22 +08:00
    @KuroNekoFan 是说 nginx 一层路由,入口 html 一层转发,app 一层路由,这样吗?好吧,如果是这样,那在只改 nginx 层面上估计是没办法了。
    感谢回复。
    orzorzorzorz
        6
    orzorzorzorz  
    OP
       2019-12-16 09:56:35 +08:00
    @KuroNekoFan 呃,没别的嘲讽的意思,你的回答的确是能绕开 nginx 的路由匹配。我原先的表达也有问题,我本来是以为只改 nginx 的配置就能实现这类路由的,只是我没翻到文档...
    KuroNekoFan
        7
    KuroNekoFan  
       2019-12-16 10:20:59 +08:00
    我说的就是 nginx 啊,当然,不能光改 nginx,还需要用配合的 webpack publicPath,和 browserRouter 的 baseName
    nginx 配置如下

    ```
    #注意这个 location map 应该要以 /结尾
    location /your/desired/path/ {
    alias $your_web_dir_root;
    #url without a dot
    location ~ ^[^.]*$ {

    try_files your_html_file.html =404;
    }
    }
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3500 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 375ms · UTC 11:03 · PVG 19:03 · LAX 04:03 · JFK 07:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.