URL 조각 및 302 리디렉션


136

URL 조각 (. 뒤에 나오는 부분 #)이 서버로 전송되지 않는다는 것은 잘 알려져 있습니다.

HTTP 상태 302 및 Location:헤더 를 통한 서버 리디렉션 이 관련 될 때 조각이 어떻게 작동하는지 궁금합니다 .

내 질문은 실제로 두 가지입니다.

  1. 원래 URL에 프래그먼트 ( /original.php#foo)가 있고로 리디렉션 된 /new.php경우 원래 URL의 프래그먼트 부분이 손실됩니까? 아니면 때로는 새 URL에 적용됩니까?
    이 경우 새 URL /new.php#foo이 사용됩니까?

  2. 원래 URL에 관계없이 서버가 조각 ( /new.php#foo) 이있는 새 URL로 리디렉션 하면 조각이 "명예"됩니까? 또는 서버가 실제로 프래그먼트를 전혀 방해하는 비즈니스가 /new.php없습니까? 따라서 브라우저는 단순히 서버로 이동하여 서버를 무시합니까 ?


1
여기서 W3C에 의해 사양을 찾을 수 있습니다 : w3.org/TR/cuap#uri clause 4.1. 조각은 리디렉션시 유지되어야합니다.
Marcin

답변:


135

2014 년 6 월 27 일 업데이트 :

RFC 7231, 하이퍼 텍스트 전송 프로토콜 (HTTP / 1.1) : 시맨틱 및 컨텐츠 가 제안 표준으로 게시되었습니다. 로부터 변경 내역 :

Location 헤더 필드의 구문은 프래그먼트 사용이 적절하지 않은 경우에 대한 설명과 함께 상대 참조 및 프래그먼트를 포함한 모든 URI 참조를 허용하도록 변경되었습니다. (7.1.2 장)

섹션 7.1.2 의 중요한 사항 . 위치 :

3xx (리디렉션) 응답으로 제공된 Location 값에 프래그먼트 컴포넌트가없는 경우, 사용자 에이전트는 값이 요청 대상을 생성하는 데 사용 된 URI 참조의 프래그먼트 컴포넌트를 상속하는 것처럼 리디렉션을 처리해야합니다 (예 : 리디렉션이 상속 함) 원래 참조의 조각 (있는 경우).

예를 들어 URI 참조 " http://www.example.org/~tim "에 대해 생성 된 GET 요청 은 헤더 필드를 포함하는 303 (기타 참조) 응답을 초래할 수 있습니다.

Location: /People.html#tim

이는 사용자 에이전트가 " http://www.example.org/People.html#tim "로 리디렉션하도록 제안합니다.

마찬가지로 URI 참조 " http://www.example.org/index.html#larry "에 대해 생성 된 GET 요청 은 헤더 필드를 포함하는 301 (영구적으로 이동) 응답을 생성 할 수 있습니다.

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

이는 사용자 에이전트 가 원래 조각 식별자를 유지하면서 " http://www.example.net/index.html#larry "로 리디렉션하도록 제안합니다 .

이것은 귀하의 질문에 분명히 대답해야합니다.

END 업데이트

이것은 현재 HTTP 스펙 과 관련된 공개 (지정되지 않음) 문제입니다 . IETF httpbis 워킹 그룹 의 2 가지 이슈에서 다루어 진다 :

# 6은 Location헤더에 조각을 허용합니다 . # 43은 이렇게 말합니다.

방금 다양한 브라우저로 이것을 테스트했습니다.

  • Firefox와 Safari는 위치 헤더에서 조각을 사용합니다.
  • Opera는 존재하는 경우 소스 URI의 조각을 사용하고, 그렇지 않으면 리디렉션 위치의 조각을 사용합니다.
  • IE (8)은 위치 URI의 조각을 무시하므로 존재하는 경우 소스 URI의 조각을 사용합니다.

신청:

"참고 : 원래 URI의 조각 식별자와 리디렉션을 결합해야하는 동작은 정의되어 있지 않습니다. 현재 사용자 에이전트는 조각이 우선하는 요소가 실제로 다릅니다."

[...]

IE8 idenfitier 조각을 사용하는 것으로 보입니다 Location(내가 본 동작은 localhost로 제한 될 수 있음).

따라서 우리는 Safari / IE / Firefox / Chrome (방금 테스트)에 대해 일관된 동작을하는 것 같습니다. 원래 URI가 무엇이든 Location 헤더의 조각이 사용되기 때문입니다.

따라서 예상 한 동작 으로 문서화 하도록 제안을 변경 합니다.

그러면 귀하의 질문에 대한 브라우저 호환성이 가장 높고 향후 증거가됩니다 (이 문제는 결국 표준화 될 것이므로).

A : 원본 URL의 조각이 삭제됩니다.

B :Location 헤더의 조각 이 존중됩니다.


1
HTTP 서버에서 설정 한 "다시 쓰기"규칙을 잊어 버렸는데 아마도 301 리디렉션으로 구현되었을 것입니다. 결과적으로 IE는 여러 리디렉션이있을 때 첫 번째 리디렉션에서 설정 한 조각 이 두 번째 소스 URI의 일부가되기 때문에 조각 식별자를 잃어 버렸습니다 .
유진 요코타

오페라 12.12는 존재할 때 위치 헤더의 단편을 존중한다.
염소

4
Chrome 및 Firefox의 현재 버전에서 : A 는 사실이 아닙니다. Firefox의 현재 버전에서 : B 는 사실이 아닙니다. 현재 해시를 사용해야하는 경우 (예 : Backbone의 라우팅 사용) 자바 스크립트 기반 리디렉션이 유일한 옵션 인 것 같습니다.
a.real.human.being

인용 된 블록 자체가 모순되는 것 같습니다. 먼저 "IE (8)는 위치 URI의 조각을 무시하므로 소스 URI의 조각을있는 경우이를 사용합니다"라고 말한 다음 "IE8이 Location의 조각 식별자를 사용하는 것 같습니다"라고 말합니다. 첫 번째가 두 번째와 다른 것을 말하는가?
davidtbernal

Chome 45.0.2454.85의 경우 B는 적용되지 않습니다. Firefox 40.0.3의 경우 B가 적용됩니다.
Jingguo Yao

44

HTTP / 3xx 리디렉션이 발생하면 Safari 5 및 IE9 이하에서 원래 URI의 조각을 삭제합니다. 응답의 Location 헤더가 프래그먼트를 지정하면 사용됩니다.

IE10 +, Chrome 11+, Firefox 4+ 및 Opera는 3xx 리디렉션을 수행 한 후 원래 URI의 단편을 모두 "재 부착"합니다.

테스트 페이지 : 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 에서이 문제에 대한 추가 토론을 참조하십시오.


2
실제로 IE10은 여전히 ​​최신 Firefox 및 Chrome 버전과 다르게 작동합니다. 간단한 리디렉션의 경우 소스 URL에서 조각을 유지하는 것 같습니다. 리디렉션 Location에 조각이 포함되어 있으면 올바르게 유지됩니다. 그러나 경로 재 지정된 경우 Location조각과 다른 3xx의 리디렉션을 통과, 그것은 알수없는이 개 이전의 행동과 일치하지 첫 번째 리디렉션에서 조각을 무시합니다. 크롬과 파이어 폭스는 지속적으로 그것을 유지합니다.
odony

당신이 맞다는 것을 확인했습니다. 이 페이지의 최종 테스트 링크를 참조하십시오 : webdbg.com/test/redir/fragment
EricLaw

11

알려 드리기 위해 적절한 사양을 찾을 수 있습니다. 모두가 어떻게 행동해야 하는지를 정의하는 w3c에 의해 : http://www.w3.org/TR/cuap#uri-4.1 절-아래 참조 :

리소스 (URI1)가 이동하면 HTTP 리디렉션은 새로운 위치 (URI2)를 나타낼 수 있습니다.

URI1에 조각 식별자 #frag가 있으면 사용자 에이전트가 도달해야하는 새 대상은 URI2 # frag입니다. URI2에 이미 조각 식별자가 있으면 #frag를 추가해서는 안되며 새 대상은 URI2입니다.

잘못됨 : 대부분의 현재 사용자 에이전트는 HTTP 리디렉션을 구현하지만 조각 식별자를 새 URI에 추가하지 않습니다.이 URI는 일반적으로 사용자가 잘못된 리소스로 인해 혼란을 겪습니다.

참고 문헌 :

HTTP 리디렉션은 HTTP / 1.1 사양 [RFC2616]의 10.3 섹션에 설명되어 있습니다. 필요한 동작은 "리디렉션 된 URL에서 조각 식별자 처리"[RURL]에 자세히 설명되어 있습니다. "PURL (Persistent Uniform Resource Locator)"이라는 용어는 HTTP 리디렉션을 통해 다른 URL을 가리키는 URL (특정 URI의 경우)을 나타냅니다. 자세한 내용은 "영구 균일 자원 로케이터"[PURL]를 참조하십시오. 예:

사용자가 http://www.w3.org/TR/WD-ruby/#changes 에서 자원을 요청하고 서버가 사용자 에이전트를 http://www.w3.org/TR/ruby/로 경로 재 지정 한다고 가정 하십시오 . 후자의 URI를 가져 오기 전에 브라우저는 조각 식별자 #changes를 추가해야합니다 ( http://www.w3.org/TR/ruby/#changes) .


0

내가 직면 한 솔루션 과 비슷한 문제를 게시 했습니다.

preserving hash in IE302 리디렉션 과 비슷한 요구 사항을 가진 사람에게 도움이되기를 바랍니다 .

링크 자체 대신 답변의 필수 부분 추가

우리는 SiteMinder응용 프로그램에서 인증을 사용 합니다.

나는 인증이 성공하면 것을 생각 SiteMinder하고있다 302 redirection사용하여 사용자 요청 응용 프로그램 페이지에 로그인 폼 숨겨진 변수value (이것은 사용자가 URL을 요청 저장 /myapp/- without hash fragment이 서버로 전송되지 않습니다 때문에)와 유사한 이름으로 redirect. 아래 샘플 양식

샘플 로그인 양식

이후 redirect숨겨진 변수 만을 포함 /myapp/해시 조각없이하고 302 리디렉션의 해시 조각이 자동으로 심지어 우리의 응용 프로그램과 우리가 우리의 응용 프로그램 코드에서하려고하는 솔루션을 밖으로 작동하지 않는 무엇에 오기 전에 IE에 의해 제거된다.

IE는 (으) /myapp/로만 리디렉션되며 앱의 기본 홈 페이지에 방문합니다 https://ourapp.com/myapp/#/home.

이 행동을 알아 내기 위해 거의 하루를 낭비했습니다.

해결책은 다음과 같습니다.

기존 값과 함께 추가하여 해시 조각을 보유 하도록 로그인 양식 숨겨진 변수 ( redirect) 을 변경했습니다 window.location.hash. 아래 코드와 유사

$(function () {
  var $redirect = $('input[name="redirect"]');
  $redirect.val($redirect.val() + window.location.hash);
});

변경 후, redirect숨겨진 변수는 사용자 요청 URL 값을 저장하고 /myapp/#/pending/requests그리고 SiteMinder그것을 리디렉션 /myapp/#/pending/requestsIE이다.

위의 솔루션은 세 브라우저 모두에서 제대로 작동합니다 Chrome, Firefox and IE.

이 문제 에 대한 자세한 설명과 솔루션제공하는 @AlexFord에게 감사합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.