Eseguire correttamente redirect_to: torna in Ruby on Rails quando referrer non è disponibile


91

Ho un problema con redirect_to :back. Sì, sono referrer.

Spesso ottengo l'eccezione

(ActionController :: RedirectBackError) "Nessun HTTP_REFERER è stato impostato nella richiesta di questa azione, quindi non è stato possibile richiamare redirect_to: back. Se si tratta di un test, assicurati di specificare request.env [\" HTTP_REFERER \ "]."

Mi rendo conto che questo è il risultato della mancata disponibilità di un referrer. C'è un modo per impostare, ad esempio, una variabile di sessione su ogni accesso con l'ultima pagina visitata e, quando HTTP_REFERER non è disponibile, utilizzare questa variabile di sessione per reindirizzare?


Ho lo stesso errore in un'azione di aggiornamento, il che è strano perché il referrer non può essere vuoto (come la richiesta sarebbe da un modulo), ma alcuni utenti sono riusciti a farlo, cosa che non so come.
lulalala

Risposte:


144

E 'improbabile che si fare avere una sessione e non hanno un referrer.

La situazione in cui un referrer non è impostato non è così rara e di solito salvo quell'aspettativa:

def some_method
  redirect_to :back
rescue ActionController::RedirectBackError
  redirect_to root_path
end

Se lo fai spesso (che penso sia una cattiva idea) puoi avvolgerlo in un altro metodo come suggerisce Maran.

BTW penso che sia una cattiva idea perché questo rende ambiguo il flusso di utenti. Solo in caso di login questo è sensato.

AGGIORNAMENTO : Come molte persone hanno sottolineato che questo non funziona più con Rails 5. Invece, usa redirect_back, questo metodo supporta anche un fallback. Il codice diventa quindi:

def some_method
  redirect_back fallback_location: root_path
end

4
Sospetto che lo altererei per usare invece rescue_from.
Bob Aman

1
@BobAman IMO potremmo usare rescue_fromse il controller avesse piùredirect_to :back
Theo B

non funziona con rails 5, ActionController :: RedirectBackError è undefined ... quale soluzione?
Matrix

Usa questo invece:redirect_to (request.referrer || root_url)
Abhi

38

Ecco il mio piccolo metodo redirect_to_back:

  def redirect_to_back(default = root_url)
    if request.env["HTTP_REFERER"].present? and request.env["HTTP_REFERER"] != request.env["REQUEST_URI"]
      redirect_to :back
    else
      redirect_to default
    end
  end

Puoi passare un URL opzionale per andare altrove se http_refferrer è vuoto.


37
def store_location
  session[:return_to] = request.request_uri
end

def redirect_back_or_default(default)
  redirect_to(session[:return_to] || default)
  session[:return_to] = nil
end

Prova questo! (Grazie al plugin Authlogic )


22
Questa è una buona soluzione, ma esorto chiunque lo utilizzi a tenere presente che può "interrompersi" in un modo estremamente confuso per l'utente se utilizza più schede per navigare nella tua app.
Mitch Lindgren

3
+1 Per aver risposto alla domanda e non aver criticato i metodi di progettazione.
Abe Petrillo,

31

Caratteristica principale

redirect_backè una funzionalità principale di Rails 5+, è disponibile nel ActionController::Redirectingmodulo che è già incluso in ApplicationController::Base.

AVVISO DI DEPRECAZIONE: redirect_to :backè deprecato e verrà rimosso da Rails 5.1. Utilizzare redirect_back(fallback_location: fallback_location)dove fallback_locationrappresenta la posizione da utilizzare se la richiesta non ha informazioni sul referer HTTP.

EDIT: fonte


Link alla fonte, per favore
Chris Bloom

1
@ Chrisbloom7 Questo è un messaggio di avviso che ho ricevuto durante l'esecuzione di Rails 5.0.0beta3 con redirect_to :back.
Cyril Duchon-Doris

21

Forse è tardi ma vorrei condividere il mio metodo che conserva anche le opzioni:

  def redirect_back_or_default(default = root_path, *options)
    tag_options = {}
    options.first.each { |k,v| tag_options[k] = v } unless options.empty?
    redirect_to (request.referer.present? ? :back : default), tag_options
  end

Puoi usarlo come:

redirect_back_or_default(some_path, :notice => 'Hello from redirect', :status => 301)

14

aggiornato: Rails 5 ha aggiunto il metodo redirect_back ( https://github.com/rails/rails/pull/22506/ ), meglio usare:

redirect_back fallback_location: answer_path(answer), flash: { error: I18n.t('m.errors')}

Per i binari inferiori a 5.0 è ancora possibile utilizzare il vecchio modo di seguito:

simile alla risposta di @ troex, aggiungilo al controller dell'applicazione

def redirect_back_or_default(default = root_path, options = {})
  redirect_to (request.referer.present? ? :back : default), options
end

quindi usalo nel tuo controller

redirect_back_or_default answer_path(answer), flash: { error: I18n.t('m.errors')}

0

Recentemente, ho riscontrato lo stesso problema in cui dovevo reindirizzare :backo verso una pagina specifica. Dopo aver trovato molte soluzioni, ho finalmente trovato questa che è semplice e sembra risolvere il problema:


if request.env["HTTP_REFERER"].present?
    redirect_to :back
else
    redirect_to 'specific/page'
end

Se vuoi usare i sessiondettagli, fallo nell'altra parte del codice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.