Чому під час виклику Response.Redirect () я отримую повідомлення "Неможливо перенаправити після надсилання заголовків HTTP"?


84

Коли я телефоную, Response.Redirect(someUrl)я отримую такий HttpException:

Не вдається перенаправити після надсилання заголовків HTTP.

Чому я отримую це? І як я можу вирішити цю проблему?

Відповіді:


120

Згідно з документацією MSDN для Response.Redirect(string url), він видасть HttpException, коли "буде зроблена спроба переадресації після відправлення заголовків HTTP". Оскільки Response.Redirect(string url)використовується заголовок відповіді Http "Location" ( 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, фільтрами винятків тощо. Ви також не можете змінити код стану відповіді HTTP, коли буде видано переспрямування 301/302.
Jaans

Я вирішив проблему, зробивши всі властивості на моїй сторінці "статичними"
Саль

4
зробити свої властивості статичними є небезпечним рішенням
розвідник

Як можна переспрямування викликати вдруге, якщо не спіймано ThreadAbortException (з першого разу)? :} "Виклик переадресації еквівалентний виклику переадресації з другим параметром ( endResponse), встановленим на true."
user2864740

1
Це дивно, але у застарілій програмі веб-форм Response.IsRequestBeingRedirectedпомилково, і я все ще отримую цей самий виняток (усередині Application_EndRequestметоду подій у Global.asax). Я не можу зрозуміти чому.
Аліссон,

17

Як тільки ви відправляєте будь-який вміст клієнту, заголовки HTTP уже надіслані. AResponse.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). Для відповіді. Перенаправити на роботу,

  1. Буферизація повинна бути правдивою,
  2. вам не слід було надсилати більше даних за допомогою response.write, який перевищує розмір буфера за замовчуванням (у такому випадку він буде змитий, спричиняючи надсилання заголовків), що забороняє вам перенаправляти.

1
Response.BufferOutput = true;в дії, в контролері?
Кікенет,


2

Ви також можете використовувати згаданий нижче код

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

1

На це є одна проста відповідь: перед надсиланням заголовка вам було видано щось інше, наприклад, текст або що-небудь пов’язане з вихідними даними з вашої сторінки. Це впливає на те, чому ви отримуєте цю помилку.

Просто перевірте свій код на можливий вихід, або ви можете поставити заголовок поверх вашого методу, щоб він був надісланий першим.


1

Якщо ви намагаєтеся переспрямувати після того, як заголовки були відправлені (якщо, наприклад, ви робите переспрямування помилки з частково створеної сторінки), ви можете надіслати якийсь клієнтський Javascript (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 і працюємо на одному контролері і переспрямовуємо на іншу дію, то вам не потрібно писати ..
Response.Redirect ("Ім'я дії", "Ім'я контролера");
краще використовувати лише
функцію return RedirectToAction ("ActionName");
або
повернути View ("ViewName");


Я використовую ActionName з іншого ControllerName?
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

Існує 2 способи виправити це:

  1. Просто додайте returnтвердження після вашого Response.Redirect(someUrl); (якщо підпис методу не є "недійсним", вам, звичайно, доведеться повернути цей "тип") так:

    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(someUrl);
return; 

вибачте, але це не має для мене сенсу. Що повинен робити (у методі повернення порожнечі) цей надлишок return? returnТільки визначає , що метод завершується. Але коли коду не залишилося, метод все одно завершено. І зберігання URL-адреси у змінній нічого не змінює, я маю на увазі: навіщо це робити? Рядок однаковий. Скомпільована річ не робить різниці між рядком і змінною, що містить рядок ...: подумайте x = 5, отже, x дорівнює 5, але 5 - це також 5. навіть 10/2 було б 5 ... не має жодної різниці
Matthias Burger
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.