Dlaczego pojawia się komunikat „Nie można przekierować po wysłaniu nagłówków HTTP”, gdy wywołuję Response.Redirect ()?


Odpowiedzi:


120

Zgodnie z dokumentacją MSDN dla Response.Redirect(string url), zgłosi HttpException, gdy „podjęto próbę przekierowania po wysłaniu nagłówków HTTP”. Ponieważ Response.Redirect(string url)używa nagłówka odpowiedzi HTTP „Location” ( http://en.wikipedia.org/wiki/HTTP_headers#Responses ), wywołanie go spowoduje wysłanie nagłówków do klienta. Oznacza to, że jeśli wywołasz go po raz drugi lub jeśli wywołasz go po tym, jak spowodowałeś wysłanie nagłówków w inny sposób, otrzymasz HttpException.

Jednym ze sposobów na uniknięcie wielokrotnego wywoływania Response.Redirect () jest sprawdzenie Response.IsRequestBeingRedirectedwłaściwości (bool) przed jej wywołaniem.

// Causes headers to be sent to the client (Http "Location" response header)
Response.Redirect("http://www.stackoverflow.com");
if (!Response.IsRequestBeingRedirected)
    // Will not be called
    Response.Redirect("http://www.google.com");

2
Tak, dokładnie. Dzieje się to dość łatwo w przypadku ASP.NET MVC 4 i filtrów wyjątków itp. Nie można również zmienić kodu stanu odpowiedzi HTTP po wydaniu przekierowania 301/302.
Jaans

Rozwiązałem ten problem, ustawiając wszystkie właściwości na mojej stronie jako „statyczne”
Sal

4
unieruchomienie nieruchomości jest niebezpiecznym rozwiązaniem
poszukiwacz

Jak można wywołać przekierowanie po raz drugi, chyba że wyjątek ThreadAbortException (od pierwszego) zostanie przechwycony? :} „Wywołanie Redirect jest równoważne wywołaniu Redirect z drugim parametrem ( endResponse) ustawionym na true”.
user2864740

1
To dziwne, ale w starszej aplikacji formularzy internetowych Response.IsRequestBeingRedirectedjest fałszywa i nadal otrzymuję ten sam wyjątek (wewnątrz Application_EndRequestmetody zdarzenia w Global.asax). Nie rozumiem dlaczego.
Alisson

17

Gdy w ogóle wyślesz jakąkolwiek zawartość do klienta, nagłówki HTTP zostały już wysłane. ZAResponse.Redirect()Wezwanie działa poprzez wysłanie specjalnego informacje w nagłówkach, które sprawiają, że przeglądarka poprosić o inny URL.

Ponieważ nagłówki zostały już wysłane, asp.net nie może robić tego, co chcesz (modyfikować nagłówki)

Możesz obejść ten problem, wykonując a) przekierowanie, zanim zrobisz cokolwiek innego, lub b) spróbuj użyć go, Response.Buffer = truezanim zrobisz cokolwiek innego, aby upewnić się, że żadne dane wyjściowe nie są wysyłane do klienta, dopóki cała strona nie zostanie wykonana.


U mnie to nie działa. Używam .NET, MVC i mam wywołanie wewnątrz metody kontrolera. Nadal otrzymuję wyjątek, chociaż zdarza się przekierowanie.
FrenkyB

8

Przekierowanie może się zdarzyć tylko wtedy, gdy pierwsza linia wiadomości HTTP to „HTTP/1.x 3xx Redirect Reason ”.

Jeśli już zadzwoniłeś Response.Write()lub ustawiłeś jakieś nagłówki, na przekierowanie będzie za późno. Możesz spróbować zadzwonić Response.Headers.Clear()przed przekierowaniem, aby sprawdzić, czy to pomoże.


Używam return RedirectToAction("Logout", "Authentication");i otrzymuję ten błąd
Kiquenet

Kiedy próbowałem wyczyścić nagłówki, otrzymałem System.PlatformNotSupportedException: Ta operacja wymaga trybu zintegrowanego potoku usług IIS.
IrishChieftain

3

Po prostu sprawdź, czy ustawiłeś opcję buforowania na false (domyślnie jest to prawda). Aby uzyskać odpowiedź. Przekierować do pracy,

  1. Buforowanie powinno być prawdziwe,
  2. nie powinieneś był wysyłać więcej danych przy użyciu response.write, który przekracza domyślny rozmiar bufora (w takim przypadku opróżni się, powodując wysłanie nagłówków), co uniemożliwia ci przekierowanie.

1
Response.BufferOutput = true;w akcji, w kontrolerze?
Kiquenet


2

Możesz również użyć poniższego kodu

Response.Write("<script type='text/javascript'>"); Response.Write("window.location = '" + redirect url + "'</script>");Response.Flush();

1

Jest na to jedna prosta odpowiedź: otrzymałeś coś innego, na przykład tekst lub cokolwiek związanego z wyjściem ze strony przed wysłaniem nagłówka. Ma to wpływ na to, dlaczego pojawia się ten błąd.

Po prostu sprawdź swój kod pod kątem możliwych wyników lub możesz umieścić nagłówek na górze metody, aby został wysłany jako pierwszy.


1

Jeśli próbujesz przekierować po wysłaniu nagłówków (jeśli na przykład robisz błąd przekierowania z częściowo wygenerowanej strony), możesz wysłać klientowi Javascript (location.replace lub location.href itp.) aby przekierować na dowolny adres URL. Oczywiście zależy to od tego, jaki HTML został już przesłany.


1

Mój problem został rozwiązany przez dodanie programu obsługi wyjątków do obsługi „Nie można przekierować po wysłaniu nagłówków HTTP”. ten błąd, jak pokazano poniżej

catch (System.Threading.ThreadAbortException)
        {
            // To Handle HTTP Exception "Cannot redirect after HTTP headers have been sent".
        }
        catch (Exception e)
        {//Here you can put your context.response.redirect("page.aspx");}

1

Rozwiązałem problem przy użyciu: Response.RedirectToRoute ("CultureEnabled", RouteData.Values); zamiast Response.Redirect.


1

Błąd Nie można przekierować po wysłaniu nagłówków HTTP.

System.Web.HttpException (0x80004005): nie można przekierować po wysłaniu nagłówków HTTP.

Sugestia

Jeśli używamy asp.net mvc i pracujemy na tym samym kontrolerze i przekierowujemy do innej akcji, nie ma potrzeby pisania ..
Response.Redirect ("ActionName", "ControllerName");
lepiej jest używać tylko
return RedirectToAction ("ActionName");
lub
return View („ViewName”);


Używam ActionName z innego ControllerName?
Kiquenet

0

Funkcja przekierowania prawdopodobnie działa przy użyciu „odświeżania” nagłówka http (i być może przy użyciu kodu 30X). Po wysłaniu nagłówków do klienta serwer nie może dołączyć polecenia przekierowania, ponieważ jest już za późno.


0

Jeśli pojawi się komunikat Nie można przekierować po wysłaniu nagłówków HTTP, wypróbuj poniższy kod.

HttpContext.Current.Server.ClearError();
// Response.Headers.Clear();
HttpContext.Current.Response.Redirect("/Home/Login",false);

0

Upewnij się, że nie używasz Responsemetod s, takich jak Response.Flush();przed częścią przekierowującą.


-3

Istnieją 2 sposoby, aby to naprawić:

  1. Po prostu dodaj returnoświadczenie po swoimResponse.Redirect(someUrl); (jeśli podpis metody nie jest "void", będziesz oczywiście musiał zwrócić ten "typ"), tak jak to:

    Response.Redirect ("Login.aspx");

    powrót;

Zwróć uwagę, że powrót umożliwia serwerowi wykonanie przekierowania ... bez niego serwer chce kontynuować wykonywanie reszty kodu ...

  1. Utwórz Response.Redirect(someUrl)OSTATNI wykonaną instrukcję w metodzie, która zgłasza wyjątek. Zastąp swój Response.Redirect(someUrl)ciąg VARIABLE o nazwie „someUrl” i ustaw go na lokalizację przekierowania ... w następujący sposób:

//......some code

string someUrl = String.Empty

..... trochę logiki

if (x=y)
{
    // comment (original location of Response.Redirect("Login.aspx");)
    someUrl = "Login.aspx";
}

...... więcej kodu

// PRZENIEŚ swoją odpowiedź Przekieruj do TUTAJ (koniec metody):

Response.Redirect(someUrl);
return; 

przepraszam, ale to nie ma dla mnie żadnego sensu. Co powinno zrobić (w metodzie zwracającej pustkę), co zbędne return? returnTylko określa, że metoda jest zakończona. Ale jeśli nie ma już żadnego kodu, metoda i tak jest zakończona. A przechowywanie adresu URL w zmiennej niczego nie zmienia, to znaczy: po co? Ciąg jest taki sam. Skompilowana rzecz nie robi żadnej różnicy między napisem a zmienną zawierającą łańcuch ...: pomyśl o tym x = 5, więc x to 5, ale 5 to także 5. Nawet 10/2 to 5 ... też nie robi różnicy
Matthias Burger
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.