新手问题 Rails 如何设置全局的 URL 前缀

zodal · September 03, 2020 · Last by huacnlee replied at September 15, 2020 · 1581 hits

想用 nginx 根据 url 前缀转发请求到 rails,所以需要给 rails 加上一个全局的 url 前缀。

试过修改 config.ru 文件为:

map '/app' do
  run Rails.application
end

但是这种方法也只是给 controller 的 url 加上了前缀,静态资源没有变化。

补充=========================

在官网上找到了这个配置,但是感觉 rails 在这个地方处理的特别矛盾。

config.relative_url_root = "/app"

这个配置会在生成链接的时候给链接加上前缀,但这个配置有两个问题:

1、只会改变静态文件的链接,controller 的链接不受影响。

2、只是修改生成到网页的链接,而不会修改实际路径。

<%= link_to image_tag("rails.png", alt: "Rails logo"), 'http://rubyonrails.org/' %>

上面的代码本来生成的链接是这样的: http://localhost/rails-b8442a7b798faf40f6c42e065d211574e1bb622495453893e625a416404177c2.png

加了配置后会变成:http://localhost/app/rails-b8442a7b798faf40f6c42e065d211574e1bb622495453893e625a416404177c2.png

但是这个只是改变了生成的 url,并不会改变实际的 url,如果真的需要拿到资源还是需要访问把 app 去掉的 url。

我想这应该是为了给 nginx 用的,由 nginx 在处理时去掉 app 前缀。

这样子和最开始的那个修改 config.ru 的方法加在一起后确实勉强能实现了,需要 nginx 配置两个转发规则一个给 controller,直接原样转发,只是改一下域名和端口;一个给静态文件,转发时去掉 app 前缀。虽然这又会导致不通过 nginx 直接访问系统时无法获取静态资源。。。

虽然这样是能解决问题,但是看着就 tm 的离谱,照理来说第一个方法就因该解决问题了,明明静态资源也是 rails 处理的。从来没在其他语言的 web 框架里见过这种事情。不知道大佬们有没有更好的方案。

可以试试用 config.assets.prefix 为静态资源配置前缀

要实现你这个要求,不必要改 rails 的前缀,只要配置 nginx 就行了:

location /api1 {
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect off;
  proxy_set_header  X-Forwarded-Ssl on;
  proxy_set_header  X-Forwarded-Port $server_port;
  proxy_set_header  X-Forwarded-Host $host;

  rewrite ^/api1(/(.+))?$ /$1 break; # 这行用来把前缀给去掉
  proxy_pass http://localhost:3000;
}

这个设置不会给 js 添加前缀

单纯的 nginx 配置不行,首页是可以访问,但是其他生成的 url 不会带上前缀,会被转发到其他地方去

看我们之前 的改造应该还有个 config.action_controller.relative_url_root 配置(3.2 版本)

或者都 不改,使用 2 楼的配置,再加些 sub_filter

sub_filter "/assets" "/app/assets";

,不过多 少会影响些性能。

但是这个只是改变了生成的 url,并不会改变实际的 url,如果真的需要拿到资源还是需要访问把 app 去掉的 url。

换个思路,正式站的静态文件都是 rake assets:precompile 过的,直接用软链接改变实际的 url 就行

ln -s ../public app

@hooopo 最近那个开源项目就有实现,可以参考一下

You need to Sign in before reply, if you don't have an account, please Sign up first.