2016-03-30 3 views
0

В моих рельсах 4 приложения Я хотел бы ответить html как для html, так и js. В тот момент, когда запрос имеет значение html, рендеринг работает нормально, но когда запрос js, тогда файл html не отображается на экране (хотя в командной строке он говорит, что он отображается).запрос и ответ на стойку синхронизации

Существуют различные сценарии для ограничения запросов, поэтому код дроссельной заслонки может быть вызван html POST и js POST.

Rack::Attack.throttle(key, limit: from_config(key, :limit), period: from_config(key, :period)) do |req| 
    if req.path.ends_with?(from_config(key, :path).to_s) && from_config(key, :method) == req.env['REQUEST_METHOD'] 
    ### This is the snippet I try to change the req type with but not working 
    if req.media_type == 'application/javascript' 
     req.media_type = 'text/html' 
    end 
    ##### till here 
    req.ip 
    end 
end 

Вот что я пытаюсь сделать. Как вы видите, это ответ html.

Rack::Attack.throttled_response = lambda do |env| 
    [429, {}, [ActionView::Base.new.render(file: 'public/429.html', content_type: 'text/html')]] 
end 

Что мне делать?

UPDATE

Это моя новая версия, но не может понять, как проверить запрос CONTENT_TYPE:

Rack::Attack.throttled_response = lambda do |env| 
    retry_after = (env['rack.attack.match_data'] || {})[10] 
    if env['rack.attack.content_type'] == 'text/html' 
    [429, {'Retry-After' => retry_after.to_s}, [ActionView::Base.new.render(file: 'public/429.html', content_type: 'text/html')]] 
    elsif env['rack.attack.content_type'] == 'application/javascript' 
    [429, {'Retry-After' => retry_after.to_s}, window.location.href = '/429.html'] 
    end 
end 

Документы https://github.com/kickstarter/rack-attack

+0

Почему бы вам не хотеть этого? Было бы разумнее создать пользовательский тип mime или использовать заголовки, чтобы проверить, является ли это XHR-запросом, а не испортить один из существующих типов mime. – max

+0

Большинство браузеров не будут отображать ответ как HTML, если запрос имеет нечто иное, чем 'accept: text/html'. – max

+0

max, можете ли вы показать мне, как это сделать? Я не знаю, почему это все испортило бы, поскольку это происходит, только если sby превышает предел для какого-либо действия. –

ответ

1

Я согласен с @Max. В принципе, вы не должны отвечать HTML на запрос специально для JS.

Но чтобы ответить на эту часть вопроса:

как проверить запрос CONTENT_TYPE:

Попробуйте проверить это вместо того, чтобы:

req.env['HTTP_ACCEPT'] 

Объяснение

  1. reqis an object that subclassesRack::Request.
  2. Rack prependsHTTP_ в заголовки HTTP-запросов клиента и добавляет их в хэш-код env.
  3. HTTP clients can indicate what MIME types they accept в заголовке Accept, в отличие от заголовка Content-Type, где они могут указывать, какой тип данных они отправляют вам.
+0

monozok, если бы вы не ответили html, тогда как бы вы решили эту проблему? Если sby, скажем, попытается войти в систему 10 раз (что html post req), то он будет перенаправлен на страницу, в которой говорится, что он сделал слишком много запросов. Но то же самое должно произойти, когда sby слишком сильно комментирует сообщение. Проблема в том, что это js-запрос, поскольку обычно (в пределах ограничения количества запросов) он должен просто отвечать с помощью js-фрагмента. Итак, как я могу ответить js, если в пределе req и с html over req limit? –

+0

Хорошо, перечитывая свою новую версию, я вижу, что вы отвечаете на JS, которая сообщает браузеру перенаправить. Поэтому у меня нет проблем с этим. Виноват! – monozok