Response.Redirect ()를 호출 할 때 "HTTP 헤더를 보낸 후 리디렉션 할 수 없습니다"라는 메시지가 나타나는 이유는 무엇입니까?


84

전화 Response.Redirect(someUrl)하면 다음과 같은 HttpException이 발생합니다.

HTTP 헤더를 보낸 후에는 리디렉션 할 수 없습니다.

왜 이것을 얻습니까? 이 문제를 어떻게 해결할 수 있습니까?

답변:


120

에 대한 MSDN 설명서에 따르면 Response.Redirect(string url)"HTTP 헤더가 전송 된 후 리디렉션이 시도 될 때"HttpException이 발생합니다. 때문에 Response.Redirect(string url)용도는 HTTP "위치"응답 헤더 ( http://en.wikipedia.org/wiki/HTTP_headers#Responses )를 호출하면 헤더를 클라이언트로 전송하게됩니다. 즉, 두 번째로 호출하거나 헤더를 다른 방식으로 전송 한 후에 호출하면 HttpException이 발생합니다.

Response.Redirect ()를 여러 번 호출하지 않도록 보호하는 한 가지 방법은 Response.IsRequestBeingRedirected호출하기 전에 속성 (bool) 을 확인 하는 것입니다.

// 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
맞아요. 이것은 ASP.NET MVC 4 및 예외 필터 등에서 매우 쉽게 발생합니다. 또한 리디렉션 301/302가 발행 된 후에는 HTTP 응답 상태 코드를 변경할 수 없습니다.
Jaans

내 페이지의 모든 속성을 '정적'으로 만들어 문제를 해결했습니다.
Sal

4
당신의 재산의 정적을 만드는 것은 위험한 솔루션입니다
광부

ThreadAbortException (처음부터)이 잡히지 않는 한 리디렉션을 두 번째로 호출하려면 어떻게해야합니까? :} "Redirect 호출은 두 번째 매개 변수 ( endResponse)를 true로 설정하여 Redirect를 호출하는 것과 같습니다 ."
user2864740

1
이상하지만 레거시 웹 양식 응용 프로그램 Response.IsRequestBeingRedirected에서 거짓이며 여전히 동일한 예외가 발생합니다 ( Application_EndRequestGlobal.asax의 이벤트 메서드 내부 ). 이유를 이해할 수 없습니다.
Alisson

17

콘텐츠를 클라이언트에 보내면 HTTP 헤더가 이미 전송되었습니다. Response.Redirect()호출은 브라우저가 다른 URL을 요청할 수 있도록 헤더의 특별한 정보를 전송하여 작동합니다.

헤더가 이미 전송되었으므로 asp.net은 원하는 작업을 수행 할 수 없습니다 (헤더 수정).

a) 다른 작업을 수행하기 전에 리디렉션을 수행하거나 b) Response.Buffer = true다른 작업을 수행하기 전에 사용 을 시도하여 전체 페이지가 실행될 때까지 출력이 클라이언트에 전송되지 않도록 할 수 있습니다.


나를 위해 그것은 작동하지 않습니다. .NET, MVC를 사용하고 컨트롤러의 메서드 내부에 호출이 있습니다. 리디렉션이 발생하더라도 여전히 예외가 발생합니다.
FrenkyB

8

리디렉션은 HTTP 메시지의 첫 번째 줄이 " HTTP/1.x 3xx Redirect Reason"인 경우에만 발생할 수 있습니다 .

이미 Response.Write()일부 헤더를 호출 하거나 설정 했다면 리디렉션하기에 너무 늦을 것입니다. Response.Headers.Clear()리디렉션 전에 전화를 걸어 도움이되는지 확인할 수 있습니다 .


내가 사용 return RedirectToAction("Logout", "Authentication");하고 난 그 오류 얻을
Kiquenet

헤더를 지우려고 할 때 System.PlatformNotSupportedException이 발생했습니다.이 작업에는 IIS 통합 파이프 라인 모드가 필요합니다.
IrishChieftain

3

버퍼링 옵션을 false로 설정했는지 확인하십시오 (기본적으로 true). response.redirect가 작동하려면

  1. 버퍼링이 참이어야합니다.
  2. 기본 버퍼 크기를 초과하는 response.write를 사용하여 더 많은 데이터를 보내지 않아야합니다 (이 경우 자체적으로 플러시되어 헤더가 전송 됨). 따라서 리디렉션을 허용하지 않습니다.

1
Response.BufferOutput = true;액션, 컨트롤러?
Kiquenet


2

아래에 언급 된 코드를 사용할 수도 있습니다.

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

1

이에 대한 간단한 대답이 하나 있습니다. 헤더를 보내기 전에 텍스트 또는 페이지의 출력과 관련된 다른 것을 출력했습니다. 이는 해당 오류가 발생하는 이유에 영향을줍니다.

가능한 출력에 대한 코드를 확인하거나 헤더를 메소드 맨 위에 놓아 먼저 전송되도록 할 수 있습니다.


1

헤더를 보낸 후 리디렉션을 시도하는 경우 (예 : 부분적으로 생성 된 페이지에서 오류 리디렉션을 수행하는 경우) 일부 클라이언트 자바 스크립트 (location.replace 또는 location.href 등)를 보낼 수 있습니다. 원하는 URL로 리디렉션합니다. 물론 그것은 이미 어떤 HTML이 전송되었는지에 달려 있습니다.


1

내 문제는 "HTTP 헤더가 전송 된 후 리디렉션 할 수 없음"을 처리하기 위해 예외 처리기를 추가하여 해결되었습니다. 이 오류는 아래 코드와 같이

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

다음을 사용하여 문제를 해결했습니다. Response.RedirectToRoute ( "CultureEnabled", RouteData.Values); Response.Redirect 대신.


1

오류는 헤더가 전송 된 HTTP 후 리디렉션 할 수 없습니다.

System.Web.HttpException (0x80004005) : HTTP 헤더를 보낸 후 리디렉션 할 수 없습니다.

제안

asp.net mvc를 사용하고 동일한 컨트롤러에서 작업하고 다른 Action으로 리디렉션하는 경우에는 쓸 필요가 없습니다 ..
Response.Redirect ( "ActionName", "ControllerName"); return RedirectToAction ( "ActionName");
만 사용하는 것이 더 좋습니다
.
또는
return View ( "ViewName");


다른 ControllerName의 ActionName을 사용하고 있습니까?
Kiquenet

0

리디렉션 기능은 '새로 고침'http 헤더를 사용하여 작동 할 수 있습니다 (그리고 30X 코드도 사용할 수 있음). 헤더가 클라이언트로 전송되면 서버가 해당 리디렉션 명령을 추가 할 방법이 없습니다. 너무 늦었습니다.


0

HTTP 헤더를 보낸 후 리디렉션 할 수 없음이 표시되면 아래 코드를 시도하십시오.

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

0

리디렉션 부분 이전 Response과 같이 s의 방법을 사용하지 마십시오 Response.Flush();.


-3

이 문제를 해결하는 방법에는 두 가지가 있습니다.

  1. return다음과 같이 Response.Redirect(someUrl); (메서드 서명이 "void"가 아닌 경우 해당 "type"을 반환해야 합니다) 뒤에 문을 추가 하면됩니다.

    Response.Redirect ( "Login.aspx");

    반환;

반환은 서버가 리디렉션을 수행 할 수 있도록합니다 ... 그것없이 서버는 나머지 코드를 계속 실행하려고합니다 ...

  1. 귀하의 확인 Response.Redirect(someUrl)예외를 던지고 방법에서 마지막으로 실행 된 문을. 당신의 교체 Response.Redirect(someUrl)로 다음과 ... "someUrl"라는 문자열 변수로하고, 리디렉션 위치로 설정합니다 :

//......some code

string someUrl = String.Empty

..... 일부 논리

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

...... 더 많은 코드

// Response.Redirect를 HERE (메서드의 끝)로 이동합니다.

Response.Redirect(someUrl);
return; 

미안하지만 이건 말이 안 돼. 리던던트 return는 무엇을해야합니까 (무효 반환 방법에서) ? 는 return유일한 방법이 완료된 것으로 정의한다. 그러나 코드가 남아 있지 않으면 어쨌든 메서드가 완료됩니다. 그리고 변수에 URL을 저장하는 것은 아무것도 변경하지 않습니다. 문자열은 동일합니다. 컴파일 된 것은 문자열과 문자열을 포함하는 변수 사이에 어떤 차이도 만들지 않습니다 ... : 생각해보세요. x = 5x는 5이지만 5도 5입니다. 10/2도 5가됩니다 ... 둘 다 차이가 없습니다
마티아스 버거
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.