如何在Sinatra中获取完整的引用URL?
我基于Ruby的Sinatra框架开发应用,其中一个功能是提供JavaScript代码供远程网站调用。我需要获取调用该JS代码的远程网站完整URL,才能针对性修改JS内容,但尝试request.referrer和request.env["HTTP_REFERER"]后,仅能拿到协议加域名的部分(比如实际得到https://www.remote.com/,但期望拿到https://www.remote.com/url-with-test-code.html)。
测试代码
Sinatra测试文件
require 'sinatra' get %r{/test} do debug = {:referrer => request.referrer, :http_referer => request.env["HTTP_REFERER"], :path_info => request.path_info, :query_string => request.query_string, :host => request.host, :url => request.url, :path => request.path} STDERR.puts debug.inspect erb "test" end
远程网站HTML(部署在http://www.remote.com/url-with-test-code.html)
<!DOCTYPE html> <html> <body> <script src="http://www.server.com/test"> test </body> </html>
当前返回结果
{:referrer=>"https://www.remote.com/", :http_referer=>"https://www.remote.com/", :path_info=>"/test", :query_string=>"", :host=>"www.server.com", :url=>"https://www.server.com/test", :path=>"/test"}
这不是Sinatra的问题,HTTP_REFERER的内容完全由浏览器决定:当通过<script>标签加载外部资源时,部分浏览器会默认只发送域名作为referrer,而非完整页面URL,这是浏览器的默认行为或安全策略导致的。可以通过以下两种方式解决:
主动让调用方传递完整URL
要求远程网站在请求JS时,通过查询参数携带当前页面的完整URL,比如将<script>标签修改为:<script src="http://www.server.com/test?referrer=https%3A%2F%2Fwww.remote.com%2Furl-with-test-code.html"></script>之后在Sinatra代码中,通过
request.params['referrer']获取该值,注意要做URL解码和合法性校验,避免恶意参数。这种方法最可靠,不依赖浏览器和远程网站的配置。配置Referrer-Policy让浏览器发送完整URL
如果远程网站可以配合调整,可让他们在页面中添加Referrer-Policy设置,强制浏览器发送完整referrer:- 方式一:添加meta标签
<meta name="referrer" content="unsafe-url"> - 方式二:在远程网站服务器配置中添加响应头
Referrer-Policy: unsafe-url
注意:
unsafe-url会暴露完整URL(包括查询参数),存在隐私泄露风险,需要评估场景是否适用。- 方式一:添加meta标签
内容的提问来源于stack exchange,提问作者Evan Appleby

