Почему перенаправление PHP не работает, когда вы передаете адрес страницы через GET?

#php #redirect #header #get #http-status-code-302

#php #перенаправление #заголовок #получить #http-status-code-302

Вопрос:

Вот мой код в redirect.php : (Я знаю, что это непрактично)

 <?php
header("Location: " . $_GET['to']);
?>
  

И вот в чем проблема. Эта страница работает и перенаправляет правильно:

 redirect.php?to=http://www.google.com
  

Но это не так:

 redirect.php?to=http://www.google.com/
  

Проблема не в последней косой черте, эта тоже не работает:

 redirect.php?to=http://www.google.com/intl/en/about/corporate/index.html
  

Также не выполняется запрос GET с urlencoded:

 redirect.php?to=http%3A%2F%2Fwww.google.com%2F
  

Но работают следующие ошибочные: (Обратите внимание на одну косую черту в http:/)

 redirect.php?to=http:/www.google.com/
redirect.php?to=http:/www.google.com/intl/en/about/corporate/index.html
  

И это вызывает ошибку 404 на моем собственном сервере, как и должно быть («Запрошенный URL www.google.com не найден на нашем сервере …»):

 redirect.php?to=www.google.com/
  

В Firefox ошибочные показывают «Соединение с сервером было сброшено», а Chrome также показывает страницу «Ошибка 101 (net :: ERR_CONNECTION_RESET): соединение было сброшено». Из-за этого я не вижу, какие заголовки отправляет сервер. На самом деле кажется, что он ничего не отправляет!

Самое смешное, что все вышеперечисленные запросы работают нормально, когда я тестирую их на своем локальном хостинге с помощью WampServer, но когда я их загружаю, это просто не работает! Перед заголовком нет выходных данных или спецификации, прокси не используется, и вся работа выполняется на порту 80. Может ли быть причиной проблемы конфигурация моего сервера (какая конфигурация?)?

Я не могу придумать ничего другого, чтобы попробовать и поэкспериментировать.

Я уже читал некоторые проблемы с перенаправлением после отправки данных POST, но я не думаю, что это связано с этой проблемой.

Редактировать:

Пробовал отправлять заголовки состояния 301/303 перед заголовком местоположения… Не повезло.
Позвонил другу и попросил его протестировать его на другом компьютере и другом провайдере … Не повезло.
Написал другой скрипт в кодировке ASCII (вместо utf8)… Не повезло.

Пожалуйста, укажите мне другие тесты и диагноз, которые я могу сделать по этой проблеме.

Комментарии:

1. работает ли это, если вы попытаетесь redirect.php?to=www.google.com/ установить заголовок на header("Location: http://" . $_GET['to']); ?

2. Вы передаете параметры, передаваемые в redirect.php , но, возможно, было бы лучше вместо этого указать заголовки, которые он генерирует. Посмотрите на них с помощью инструментов разработчика.

3. @positiv: это работает, но есть много ссылок на redirect.php и в моей базе данных уже есть довольно большая база перенаправляемых ссылок, которую я не хочу менять.

4. @Jon: Не могли бы вы дать больше информации?

5. @Полковник Шрапнель: На самом деле нет. Я неправильно подумал, что он пытается передать символы из unsafe группы, как определено в RFC 1945 , что действительно является проблемой.

Ответ №1:

это не так: redirect.php?to=http: //www.google.com/

Отрицательно.

Также не работает запрос GET с urlencoded: redirect.php?to=http://www.google.com/

Отрицательно.

Оба работают.
Вы должны отладить свой код, чтобы найти, в чем проблема.

  • Вместо того, чтобы выполнять перенаправление и угадывать результаты, выведите полученное значение на экран и изучите его
  • вместо просмотра фиктивных ошибок браузера вы должны просматривать фактические HTTP-заголовки, отправленные в браузер.

Я полагаю, что это какой-то код в redirect.php портит ваши данные. Что-то вроде глупой процедуры «одновременного обеспечения безопасности всех данных».

Комментарии:

1. Как я уже объяснял, поскольку Chrome и Firefox отображали свою Connection Reset страницу с ошибкой, как DevTools, так и FireBug не смогли показать мне какие-либо заголовки. Пожалуйста, покажите мне какой-нибудь инструмент, способный показывать заголовки страниц, которые не загружаются?

2. @Col. Sharpnel: Ах, также, как я уже говорил, он ОТЛИЧНО работает на моем локальном компьютере с использованием WAMP, проблема возникает, когда я действительно загружаю его на сервер. Существует ли какая-то конфигурация сервера, которая управляет поведением таких вещей?

3. сбрасывается ли он, если вы не перенаправляете, а просто выводите значение?

4. В Chrome devtools откройте вкладку сеть, прежде чем обращаться к redirect.php сценарий. Он может показать вам фактические отправляемые и полученные заголовки.

5. @Col.Shrapnel: Нет. <?php $r = "Location: " . $_GET['to']; echo $r; header($r); ?> выводит правильный вывод: Location: http://www.google.com/ Warning: headers already sent...

Ответ №2:

Почему бы не передать его как urlencode(base64_encode($url)) , а затем перенаправить как base64_decode(urldecode($url)) .

Это не решает проблему, но мне было бы интересно узнать, работает ли это (это может помочь определить основную проблему).

Комментарии:

1. Кодировка Base 64 работает. Это header("Location: http://" . $_GET['to'] . '/'); тоже работает, но меня это не интересует.

2. Я не собираюсь использовать base64 в окончательной реализации. @ErgoSummary: кто-то отклонил каждое сообщение в этом вопросе: S

Ответ №3:

Разве вы не можете реализовать что-то подобное…

Перейдите по URL http://website.com/redirect.php?to=google.com

а затем добавьте нужные биты в URL-адрес в вашем PHP-коде, например:

 <?php
header("Location: http://" . $_GET['to']  . '/');
?>
  

Вы можете попробовать закодировать URL-адрес, а затем декодировать его в своем скрипте, чтобы предотвратить аномалии

 echo '<a href="redirect.php?to=' , urlencode("http://www.google.com/") , '">Click Here</a>';
  

а затем расшифруйте его для перенаправления

 <?php
header("Location: " . urldecode($_GET['to']) );
?>
  

Комментарии:

1. Некоторые из моих ссылок могут быть ftp, smtp, какими угодно. И на моем сайте полно ссылок на redirect.php — Я не хочу менять каждый случай. Я ищу более общий способ. И нет, urlencode не помогло (как вы уже видели в примерах.) Кстати, разве вы не знали urldecode , что его не следует использовать для элементов $ _GET?

2. Оба решения не имеют смысла, в то время как оригинальный подход OP в порядке. Чрезвычайно обманчивый ответ.

3. Я согласен, обманчивый ответ, спасибо Люку Коултону; но уже пробовал, но безуспешно.

4. Немного поздно, но » urldecode не должно использоваться для элементов $ _GET » скорее будет » urldecode не нужно использовать для элементов $ _GET «. Однако бывают редкие случаи, когда это фактически искажает данные GET. Например, случаи, когда пользователь хочет отправить символ или строку в %-кодировке буквально.

5. @Hossein Бесполезно — вероятно. Или просто не то, что вы ищете? Это фраза, которую вы хотели сказать! Кажется, здесь есть небольшая путаница в значении «обманывать». Некоторые ответы, которые не являются правильными, но могут послужить искрой для формирования других идей, что поможет найти решение.

Ответ №4:

Вы пытались искать какие-либо печатные символы вне тегов php? Это приведет к молчаливому прерыванию перенаправления.

Попробуйте оставить тег php открытым,. это решит проблемы с пробелами после закрывающего тега php. Что-то вроде этого

 <?php
header("Location: " . $_GET['to']);
// no closing tag and no content after
  

Кроме этого, включен ли этот код в другой фрагмент кода, который мог напечатать что-то в html перед вызовом заголовка?

Комментарии:

1. Я был осторожен с пробелами, новыми строками, символами спецификации, чем угодно. Файл не включен и не включает.

Ответ №5:

Вы никогда не должны использовать необработанные входные данные для отправки заголовков, поскольку это делает ваше приложение уязвимым для атак с разделением ответов.

Вы можете найти несколько хороших примеров на веб-сайте SecuriTeam.

Комментарии:

1. Это всего лишь минимальный пример. В реальной реализации сначала проверяется адрес, чтобы убедиться, что он существует в жестко заданном массиве допустимых ссылок. Спасибо за полезную ссылку.