有没有办法知道页面请求是否来自同一个应用程序?

时间:2011-10-25 14:15:00

标签: ruby-on-rails ruby-on-rails-3 request referrer

在Rails3中,有没有办法检查我现在呈现的页面是否是从同一个应用程序请求的,而不使用硬编码的域名?

我目前有:

def back_link(car_id = '')
  # Check if search exists
  uri_obj = URI.parse(controller.request.env["HTTP_REFERER"]) if controller.request.env["HTTP_REFERER"].present?
  if uri_obj.present? && ["my_domain.com", "localhost"].include?(uri_obj.host) && uri_obj.query.present? && uri_obj.query.include?('search')
    link_to '◀ '.html_safe + t('back_to_search'), url_for(:back) + (car_id.present? ? '#' + car_id.to_s : ''), :class => 'button grey back'
  end
end

但这并没有检查“www”。在域名和所有其他可能的情况下。

如果我能找到上一页(推荐人)中使用的特定控制器和操作,那也很好。

3 个答案:

答案 0 :(得分:11)

我认为你看错的方式。

如果你环顾网络,找到一个带有搜索功能的网站,然后点击链接,你会看到一个显示搜索内容的参数。

这是一个很好的方法。

HTTP_REFERER执行此操作似乎有点脆弱,例如,从书签或发布的链接无效。

例如

/cars/12?from_search=sports+cars

然后你可以查看params[:from_search]

如果您确实需要HTTP_REFERER执行此操作,那么您可能不必担心子域名。刚刚;

def http_referer_uri
  request.env["HTTP_REFERER"] && URI.parse(request.env["HTTP_REFERER"])
end

def refered_from_our_site?
  if uri = http_referer_uri
    uri.host == request.host
  end
end

def refered_from_a_search?
  if refered_from_our_site?
    http_referer_uri.try(:query)['search']
  end
end

答案 1 :(得分:2)

尝试这样的事情:

ref = URI.parse(controller.request.env["HTTP_REFERER"])

if ref.host == ENV["HOSTNAME"]
  # do something

尝试从引用页面获取控制器/操作:

ActionController::Routing::Routes.recognize_path(url.path)
  #=> {:controller => "foo", :action => "bar"}

答案 2 :(得分:0)

使用internal_request?创建request.referrer方法。

host的{​​{1}}和port与您的应用request.referrerhost进行比较。

port

然后在需要的地方调用它,最有可能在require 'uri' # Might be necesseary. def internal_request? return false if request.referrer.blank? referrer = URI.parse( request.referrer ) application_host = Rails.application.config.action_mailer.default_url_options[ :host ] application_port = Rails.application.config.action_mailer.default_url_options[ :port ] return true if referrer.host == application_host && referrer.port == application_port false end

application_controller.rb

一些警告:

  • 如果您正在使用子域,则可能需要进行修改。虽然容易。
  • 这将要求您在配置中为ActionMailer设置主机和端口,这很常见。
  • 您可能想要反过来,例如if internal_request? do_something end ,因为您可能会独特地处理这些情况。这可以让你做这样的事情:

    external_request?