URL-фрагмент и 302 перенаправления

Хорошо известно, что фрагмент URL-адреса (часть после #) не отправляется на сервер.

Я действительно задаюсь вопросом, как работают фрагменты при перенаправлении сервера (через HTTP-статус 302 и заголовок Location:).

Мой вопрос действительно двукратный:

  • Если исходный URL-адрес имеет фрагмент (/original.php#foo), а перенаправление делается на /new.php, часть фрагмента исходного URL-адреса просто теряется? Или иногда он применяется к новому URL-адресу?
    В этом случае новый URL будет /new.php#foo?

  • Независимо от исходного URL-адреса, если сервер перенаправляет на новый URL-адрес с фрагментом (/new.php#foo), будет ли фрагмент получать "честь"? Или сервер действительно не вмешивается в этот фрагмент, и браузер игнорирует его, просто перейдя в /new.php

Ответ 1

Обновление 2014-Jun-27:

RFC 7231, протокол передачи гипертекста (HTTP/1.1): семантика и контент, опубликован как ПРЕДЛАГАЕМЫЙ СТАНДАРТ. Из Список изменений:

Синтаксис поля заголовка Location был изменен, чтобы все Ссылки на URI, включая относительные ссылки и фрагменты, вдоль с некоторыми разъяснениями относительно того, когда использование фрагментов не будет подходящее. (Раздел 7.1.2)

Важные моменты из Раздел 7.1.2. Расположение:

Если значение местоположения, указанное в ответе 3xx (перенаправление), не иметь компонента фрагмента, пользовательский агент ДОЛЖЕН обрабатывать перенаправление, как будто значение наследует компонент фрагмента URI ссылка, используемая для создания целевой цели (то есть перенаправления наследует исходный ссылочный фрагмент, если он есть).

Например, Запрос GET, сгенерированный для ссылки URI " http://www.example.org/~tim" может привести к 303 (см. другие) ответ, содержащий поле заголовка:

Location: /People.html#tim

который предполагает, что пользовательский агент перенаправляется на " http://www.example.org/People.html#tim"

Аналогично, запрос GET, сгенерированный для ссылки URI " http://www.example.org/index.html#larry" может привести к 301 (перемещен Постоянно), содержащий поле заголовка:

Location: http://www.example.net/index.html

который предполагает, что пользовательский агент перенаправляется на " http://www.example.net/index.html#larry", сохраняя оригинал идентификатор фрагмента.

Это должно четко ответить на ваши вопросы.

Обновить END

это открытая (не указанная) проблема с текущей спецификацией HTTP. он адресован в 2 выпусках рабочей группы IETF httpbis:

# 6 позволяет фрагменты в заголовке Location. # 43 говорит следующее:

Я просто тестировал это с помощью различных браузеров.

  • Firefox и Safari используют фрагмент в заголовке местоположения.
  • Opera использует фрагмент из исходного URI, если присутствует, иначе фрагмент из адреса перенаправления
  • IE (8) игнорирует фрагмент в URI местоположения, поэтому будет использовать фрагмент из исходного URI, если присутствует

Предложение:

"Примечание: поведение, когда идентификаторы фрагментов из исходного URI и перенаправления необходимо объединить, undefined, текущие пользовательские агенты действительно отличаются от того, какой фрагмент имеет приоритет."

[...]

Похоже, что IE8 использует идентификатор idenfitier от Location (поведение, которое я видел, может быть ограничено локальным хостом).

Таким образом, мы, похоже, придерживаемся последовательного поведения для Safari/IE/Firefox/Chrome (только что протестировано), поскольку используется фрагмент из заголовка Location, независимо от того, что изначально был URI.

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

это приводит к наиболее совместимому с браузером и будущему доказательству (потому что эта проблема в конечном итоге будет стандартизирована) ответит на ваш вопрос:

A: фрагменты из исходных URL-адресов отбрасываются.

B: фрагменты из заголовка Location отмечены.

Ответ 2

Safari 5 и IE9 и ниже удаляют исходный фрагмент URI, если происходит перенаправление HTTP/3xx. Если заголовок Location в ответе указывает фрагмент, он используется.

IE10 +, Chrome 11+, Firefox 4+ и Opera будут "повторно прикреплять" исходный фрагмент URI после перенаправления 3xx.

Страница тестирования: http://www.webdbg.com/test/redir/fragment/.

См. дальнейшее обсуждение этой проблемы на http://blogs.msdn.com/b/ieinternals/archive/2011/05/17/url-fragments-and-redirects-anchor-hash-missing.aspx

Ответ 3

Просто, чтобы вы знали, здесь вы можете найти подходящую спецификацию. w3c определяет, как все должно вести себя: http://www.w3.org/TR/cuap#uri - пункт 4.1 - см. ниже:

Когда ресурс (URI1) перемещен, перенаправление HTTP может указывать его новое местоположение (URI2).

Если URI1 имеет идентификатор фрагмента #frag, то новая цель, пользовательский агент должен пытаться достичь URI2 # frag. Если URI2 уже имеет идентификатор фрагмента, тогда #frag не должен быть добавлен и новой целью является URI2.

Неправильно: большинство современных пользовательских агентов реализуют перенаправления HTTP, но не добавьте идентификатор фрагмента в новый URI, который обычно путает пользователя, потому что у него заканчивается неправильный ресурс.

Литература:

Переадресация HTTP описана в разделе 10.3 протокола HTTP/1.1 спецификация [RFC2616]. Требуемое поведение подробно описано в разделе "Обработка идентификаторов фрагментов в перенаправленных URL" [RURL]. термин "Постоянный унифицированный указатель ресурсов" (PURL) "обозначает URL (a специальный случай URI), который указывает на другой через HTTP перенаправления. Для получения дополнительной информации см." Постоянный унифицированный ресурс "Locators" [PURL]. Пример:

Предположим, что пользователь запрашивает ресурс в http://www.w3.org/TR/WD-ruby/#changes, и сервер перенаправляет user agent http://www.w3.org/TR/ruby/. Перед извлечением последнего URI, браузер должен добавить к нему идентификатор фрагмента #changes: http://www.w3.org/TR/ruby/#changes.