【发布时间】:2012-10-14 18:07:16
【问题描述】:
在 Camping/Rack 中,如何获取我的应用的基本 URL?我想知道,所以我可以把它放在它发送的电子邮件中。
可能(正在开发中)
或
http://localhost:9292
或
http://localhost:80/game
或在生产中
http://fancy-snake.heroku.com
【问题讨论】:
在 Camping/Rack 中,如何获取我的应用的基本 URL?我想知道,所以我可以把它放在它发送的电子邮件中。
可能(正在开发中)
或
http://localhost:9292
或
http://localhost:80/game
或在生产中
http://fancy-snake.heroku.com
【问题讨论】:
目前为止
url = @env['rack.url_scheme'] + "://" + @env['HTTP_HOST'] + R(LoginX, u.secret)
这似乎适用于第一种和第三种情况。不知道app在localhost/prefix是否写
【讨论】:
你必须小心一点,因为有一些潜在的陷阱。 Rack::Request class 在这里可能会有所帮助。
首先,您无法真正获取 app 的 url,因为它可能会响应多个 url(通过 Rack 路由、Apache 配置等),因此您正在寻找特定 request 的 url。如果您只处理来自一个 url 的请求,这无关紧要。
请求的方案在rack.url_scheme 下的env 散列中,但这仅适用于请求的“最后一站”。如果您的应用程序位于某种代理(Nqinx、Apache 等)之后,那么您想要获取真实请求的方案,而不是从代理到运行您的应用程序的机器的请求。如果您正确配置了代理,它应该设置一个标头,以便您知道原始方案是什么。 Rack::Request has a scheme method 将这些标头考虑在内。
url 的主机可能在HTTP_HOST 键下的env 散列中,但此标头不一定存在(诚然,如今这不太可能)。您应该依靠SERVER_NAME 和SERVER_PORT。此外还有处理代理请求的问题,您需要原始请求的主机名,而不是后端服务器。同样,Rack::Request 提供了处理这些问题的 host_with_port 和 host 方法。
Rack::Request 还提供了一个base_url method,它结合了方案和主机,并且仅在与默认端口(80 或 443)不同时才包含端口。
您的应用安装位置在SCRIPT_NAME 键下的env 哈希中。在您的第二个示例中,这将是/game,如果您的应用程序安装在服务器的根目录,则可以为空。同样,Rack::Request 提供了一个 script_name method,尽管它只是返回 env 哈希中的条目的值。
所以,总而言之,您可能想要使用这样的东西:
req = Rack::Request.new env
url = req.base_url + req.script_name
它看起来很简单,但正在为您处理各种可能性。
此外,您可能会发现 Rack specification 对阅读很有用,它包含应该在 env 哈希中的各种条目的详细信息。
【讨论】:
Camping 有一个名为 URL 的助手,它可以将绝对 URL 返回到您的应用:
URL() # => #<URL:http://test.ing/blog/>
URL() + "view/12" # => #<URL:http://test.ing/blog/view/12>
URL("/view/12") # => #<URL:http://test.ing/blog/view/12>
【讨论】: