Есть ли способ узнать, пришел ли запрос страницы из того же приложения? - PullRequest
4 голосов
/ 25 октября 2011

В 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 ]

11 голосов
/ 25 октября 2011

Я думаю, что вы смотрите на это неправильно.

Если вы посмотрите в Интернете, найдите сайт с функцией поиска и перейдите по ссылке, вы увидите параметр, показывающий, что искали.

Это хороший способ сделать это.

Выполнение этого с помощью 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
2 голосов
/ 25 октября 2011

Попробуйте что-то вроде этого:

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"}
0 голосов
/ 13 апреля 2016

Создание метода internal_request? с использованием request.referrer.

Сравните host и port request.referrer с host и 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:

if internal_request?
  do_something
end

Некоторые предостережения:

  • Это может потребоваться изменить, если вы используете субдомены. Легко, хотя.
  • Это потребует от вас установки вашего хоста и порта для ActionMailer в вашей конфигурации, что является обычным явлением.
  • Возможно, вы захотите сделать все наоборот, как external_request?, поскольку вы, вероятно, обрабатываете эти ситуации уникально. Это позволит вам сделать что-то вроде этого:

    do_something_unique if external_request?
    
...