Подтвердить что ты не робот

Rails - перенаправление на текущий URL-адрес без одного из параметров GET

У меня очень простая проблема в приложении Rails, что я не могу найти элегантное решение.

У меня есть URL-адрес: http://www.example.com/some-path/?foo=123&baz=456

И я хочу обработать один из параметров и сделать перенаправление: http://www.example.com/some-path/?baz=456

Я хочу, чтобы это работало вообще для любого URL с параметром "foo", поэтому я не хочу указывать "baz" в коде перезаписи.

Я хочу что-то вроде:

redirect_to request.path, :params => request.query_parameters.except(:foo)

За исключением того, что это не совсем работает. Я знаю, что я могу регулярное выражение или разбор строки запроса вручную, но я предполагаю, что лучший способ.

4b9b3361

Ответ 1

Лучшим способом, который я нашел до сих пор, является использование:

url_for(params.except(:obsolete_param_name))

UPDATE

Как упоминалось в grosser, это откроет дыру в вашем приложении, поскольку злоумышленник может передать хост в качестве параметра url и перенаправить пользователя на другой веб-сайт, Чтобы предотвратить это, вы можете использовать rap1ds предложение и указать, что нужно использовать только путь.

Для этой цели вы можете использовать вспомогательную функцию:

def secure_path_for(params, *excluded_params)
  url_for(params.except(*excluded_params).merge(only_path: true))
end

Ответ 2

Как просто удалить параметры [: foo], прежде чем передавать его. Может быть, что-то вроде:

params.delete[:foo]
redirect_to request.path, :params => params

Это не очень элегантно, но добавляет только одну строку. Парамс, между прочим, является вспомогательным методом, который получает параметры тока url

Ответ 3

uri = URI.parse(request.url)
new_query = uri.query.split("&").reject{|pair|
  k,v = pair.split("=")
  k =~ /^foo\[?/ # reject params named "foo" or "foo[anything"
}.join("&")
# if the new querystring is empty, assign nil instead of "" so we don't
# end up with a solitary question mark at the end of the url.
uri.query = (new_query.empty? ? nil : new_query)
redirect_to uri.to_s

Я пришел к вышеупомянутому решению после того, как столкнулся с некоторыми неочевидными проблемами, пытаясь сделать что-то "Rails way", если есть такой способ, чтобы решить эту проблему. Например:

  • Разбор параметров Rails автоматически создает экземпляры массивов и хэшей для параметров запроса, которые используют специальный синтаксис квадратной скобки: ?x[a]=1&y[]=2 становится {"x"=>{"a"=>"1"}, "y"=>["2"]} и т.д., поэтому код, который использует предоставленные процедуры запроса и парамагменты, с трудом справляется это. И фильтрация параметров с помощью необработанного значения строки может быть затруднена. Даже модуль CGI без рельсов/стойки даст вам массивы вместо строк для значений параметров.
  • Рельсы params содержат как GET, POST, так и параметры маршрутизации, такие как :action и :controller, поэтому вы не можете просто повторно использовать это, чтобы в любом случае восстановить цепочку.
  • Таким образом, помощники URL, такие как url_for, не очень помогают.

Учитывая эти проблемы, я обнаружил, что не смог использовать предоставленные функциональные возможности фреймворка, чтобы получить чистую и невозвращенную последовательность запросов, воспроизведенную как есть из текущего запроса, которая просто и только удаляет один параметр. Однако код выше работает хорошо.

Ответ 4

В рельсах 5 вы получите несанитарные параметры запроса, если вы попытаетесь сделать это url_for(params.except(:param))

Итак, я нашел способ сделать это:

request_url = request.url # eg. http://qwe.com/path?param1=1&param2=2

query_hash = Rack::Utils.parse_query(URI.parse(request_url).query).except('param1')
url = query_hash.empty? ? request.path : "#{request.path}?#{query_hash.to_query}"

puts url #=> /path?my_param2=2

redirect_to url