2016-03-30 20 views
0

In meiner rails 4 app möchte ich mit html sowohl für html und js anfrage antworten. In dem Moment, wenn die Anfrage html Typ ist, funktioniert das Rendering gut, aber wenn die Anfrage js ist, dann wird die HTML-Datei nicht auf dem Bildschirm gerendert (obwohl in der Befehlszeile heißt es gerendert).sync rack anfrage und antwort

Es gibt verschiedene Szenarien zur Begrenzung von Anforderungen, so dass der Drosselklappencode auch durch die Anforderung html POST und js POST ausgelöst werden kann.

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 

Hier ist, was ich versuche zu rendern. Wie Sie sehen, ist dies html Antwort.

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

Was soll ich tun?

UPDATE

Dies ist meine neueste Version, aber nicht herausfinden können, wie die Anfrage content_type zu überprüfen:

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 

docs: https://github.com/kickstarter/rack-attack

+0

Warum in aller Welt möchten Sie das tun? Es wäre sinnvoller, einen benutzerdefinierten MIME-Typ zu erstellen oder Header zu verwenden, um zu prüfen, ob es sich um eine XHR-Anfrage handelt, anstatt einen der vorhandenen MIME-Typen zu stören. – max

+0

Die meisten Browser werden die Antwort nicht als HTML ausgeben, wenn die Anfrage etwas anderes als "accept: text/html" hat. – max

+0

Max, kannst du mir zeigen, wie das geht? Ich weiß nicht, warum das irgendwas kaputt machen würde, da dies nur passiert, wenn sby das Limit für irgendeine Aktion überschreitet. –

Antwort

1

ich mit @Max zustimmen. Im Prinzip sollten Sie nicht mit HTML auf eine Anfrage speziell für JS antworten.

Aber diesen Teil der Frage zu beantworten:

wie die Anforderung content_type überprüfen:

Versuchen Sie stattdessen Überprüfung:

req.env['HTTP_ACCEPT'] 

Erklärung

  1. reqis an object that subclassesRack::Request.
  2. Rack prependsHTTP_ zu den HTTP-Anforderungsheadern des Clients und fügt sie dem env-Hash hinzu.
  3. HTTP clients can indicate what MIME types they accept in der Accept Kopfzeile, im Gegensatz zu der Content-Type Kopfzeile, wo sie angeben können, welche Art von Daten sie an Sie senden.
+0

Monozok, wenn Sie keine HTML-Antwort tun würden, wie würden Sie dann dieses Problem lösen? Wenn sby sagen wir mal versuchen, sich 10 mal anzumelden (was ein html post req) dann wird er auf eine Seite umgeleitet, die sagt das er zu viele Anfragen gemacht hat. Dasselbe sollte jedoch passieren, wenn sby zu viel Kommentare zu einem Post-Thread macht. Das Problem ist, dass es eine js-Anfrage ist, da normalerweise (innerhalb des req-Nummernlimits) es nur mit einem js-Snippet antworten sollte. Also wie kann ich mit js antworten, wenn innerhalb von req limit und mit html über req limit? –

+0

Ok, lesen Sie Ihre neueste Version, ich sehe, Sie reagieren mit JS, die den Browser anweist, umzuleiten. Also habe ich damit kein Problem. Mein Fehler! – monozok