HTTP에 POST 리디렉션이없는 이유는 무엇입니까?


162

HTTP 리디렉션은 HTTP 코드 301 및 302 (다른 코드 일 수도 있음)와 새 위치의 주소가있는 "Location"이라는 헤더 필드를 통해 수행됩니다. 그러나 브라우저는 항상 해당 URL에 "GET"요청을 보냅니다.

그러나 POST를 통해 사용자를 다른 도메인으로 리디렉션해야하는 경우가 많습니다 (예 : 은행 결제). 이것은 일반적인 시나리오이며 실제로 요구 사항입니다. HTTP 사양에서 이러한 공통 요구 사항이 무시 된 이유를 아는 사람이 있습니까? 해결 방법은 조치가있는 양식 (숨겨진 필드의 매개 변수 포함)을 대상 위치 ( Location 헤더 필드 값)로 설정 setTimeout하고 양식을 대상 위치에 제출하는 데 사용 하는 것입니다.


1
찾고있는 상태 코드 307입니까? 아래 답변을 참조하십시오.
David Ruttka

답변:


180

HTTP 1.1에는 실제로 동일한 코드 를 사용하여 요청을 반복 하고 데이터를 게시 해야 함을 나타내는 상태 코드 ( 307 )가 있습니다 .

다른 사람들이 말했듯이, 여기 에 오용가능성 이 있으며, 이는 많은 프레임 워크가 추상화에서 301과 302를 고수하는 이유 일 수 있습니다. 그러나 적절한 이해와 책임감있는 사용법으로 원하는 것을 달성 할 수 있어야합니다.

즉 따른 주 W3.org 사양 (가)하면 METHOD없다 HEAD거나 GET, 사용자 에이전트는 사용자에게 프롬프트한다 새로운 위치에 요청을 다시 실행하기 전에. 또한 오래된 사용자 에이전트가 307로 수행 할 작업을 모를 경우 사용자 에게 메모 및 대체 메커니즘제공 해야합니다 .

이 양식을 사용하여 :

<form action="Test307.aspx" method="post">
    <input type="hidden" name="test" value="the test" />
    <input type="submit" value="test" />    
</form>

그리고 Test307.aspx가 Location : http://google.com , Chrome 13 및 Fiddler 와 함께 307을 반환 하면 "test = the test"가 실제로 Google에 게시되어 있는지 확인합니다. 물론 Google은 POST를 허용하지 않지만 메커니즘을 보여주기 때문에 추가 응답은 405입니다.

자세한 정보 는 HTTP 상태 코드 목록W3.org 스펙을 참조하십시오 .

307 임시 리디렉션 (HTTP / 1.1부터)이 경우 다른 URI로 요청을 반복해야하지만 이후의 요청은 여전히 ​​원래 URI를 사용할 수 있습니다. 2 303과 달리 원래 요청을 다시 발행 할 때 요청 방법을 변경해서는 안됩니다. 예를 들어 다른 POST 요청을 사용하여 POST 요청을 반복해야합니다.


2
@DavidRuttka, 야생에서 브라우저 지원 무엇입니까 ?
Pacerier

5
@DavidRuttka 당신은 rfc7231을 고려하기 위해 답을 업데이트하고 싶을 수도 있습니다 (rfc2616은 더 이상 사용되지 않습니다). 사용자에게 프롬프트는 rfc2616의 요구 사항을 기반으로합니다. 이 요구 사항은 rfc7231에서 제거되었으며 rfc7231에서는 307 리디렉션이 요청 방법을 변경해서는 안된다는 요구 사항을 제시합니다 (견적서에 답의 끝이라고 언급).
nibarius

tools.ietf.org/id/draft-hunt-http-rest-redirect-00.html 에 따르면 "서비스 제공 업체가 클라이언트가 실제로 사용자임을 인식하지 않는 한 HTTP 리디렉션 코드 301-306을 사용해서는 안됩니다. 에이전트 "따라서 ReSTful 서비스는 301 대신 308을 사용해야합니다. 그러나 이것은 초안입니다.
브루스 아담스

49

페이지에서 좋은 설명을 찾았 습니다 .

WWW에서 가장 간단한 상황은 "무능한"거래, 즉 해를 끼치 지 않고 반복 될 수있는 거래입니다. 이들은 일반적으로 간단한 URL 참조 (예 : HTML의 href = 또는 src = 속성)를 검색하거나 GET 메소드를 사용하여 양식을 제출하기 때문에 "GET"트랜잭션입니다. 이러한 종류의 트랜잭션을 리디렉션하는 것은 간단하며 질문이 없습니다. 클라이언트는 새 URL을 지정하는 Location : 헤더를 포함하여 리디렉션 응답을 수신하고 클라이언트는 새 URL에 트랜잭션을 다시 발행하여 이에 응답합니다. 암시 된 캐시 가능성에서 이러한 리디렉션과 관련된 30x 상태 코드마다 다른 차이가 있지만 그렇지 않으면 기본적으로 GET 요청에 대한 응답이 유사합니다 (301 및 302).

POST 거래는 원칙적으로 비영리적인 것으로 정의되어 있기 때문에 (예 : 피자 주문, 투표 등) 임의로 반복해서는 안됩니다.

HTTP 프로토콜 사양은 이러한 차이점을 고려하여 설계되었습니다. GET 메소드는 본질적으로 dem 등원 인 것으로 정의되는 반면 POST 메소드는 적어도 잠재적으로 비 등방성으로 정의됩니다. 이 사양은 클라이언트 에이전트 (예 : 브라우저)가 의도하지 않은 POST 트랜잭션을 실수로 (재) 제출하거나 원하지 않는 컨텍스트에 POST를 제출하지 못하도록 사용자를 보호하기 위해 여러 가지 예방 조치를 요구합니다. .

필자는 원치 않는 신체 상해를 일으키거나 응용 프로그램에 원치 않는 피해를 입히는 것을 방지하기 위해 기술적으로 사용자를 구애하는 팬이 아니지만 요점을 이해하고 의미가 있습니다.


많은 추론이 intertubes가 느리고 신뢰할 수없는 시대에 왔습니다 (여전히 많은 지역에 있습니다). 전화를 걸었을 때를 기억하고 다른 사람이 전화를받을 때마다 임의로 연결이 끊어집니다. 페이지를 다시로드하고 서버를 다시 제출하고 동일한 조치를 두 번 수행하는 것보다 서버의 상태를 확인하는 것이 좋습니다.
zzzzBov

@ 팔콘, "방문자 카운터"를 늘리는 것이 비등 전성으로 간주됩니까? 그렇다면, 요즘 에는 websites
등한

@Pacerier : 일반적으로 dem 등원은 예를 들어, 두 번의 방문을 기록하지 않고 동일한 품목을 두 번 구매하는 것과 같이 "의미있는 방식으로 등방성"인 것으로 해석됩니다. 그렇지 않으면, 당신은 아주 옳을 것입니다. 그러나 실제로 스펙은 중복을 방지하기 위해 페이지에 ID를 삽입하는 등 서버가 필요에 따라 의미가 ent 등할 수 있어야했습니다. 브라우저가 사용자에게 정확하게 대답 할 방법이없는 질문을하지 않아도됩니다. 어쨌든 POST의 리디렉션을 막는 것은 dem 등성에 영향을 미치지 않습니다. 단순히 요청의 목표가 실제로 있다는 메시지입니다.
Lawrence Dol

나는 이것이이 추론에 어떻게 의미가 있는지 알지 못한다. 체이스 은행 웹 사이트에 있고 양식을 제출한다고 가정 해 보겠습니다. 나는 이미 동의 / 신뢰했습니다. 따라서 해당 데이터를 다른 페이지로 리디렉션해야하는 경우 왜 다시 동의해야합니까? 또는 다른 예로, 기본적으로 JavaScript를 끄는 사람이라고 가정하십시오. 어느 날 온라인으로 모기지 앱을 작성하고 양식을 제출하면 오류가 발생합니다. 앱이 방금 채워진 페이지로 데이터를 리디렉션 (POST 포함) 할 수 있다면 좋을 것입니다.
b01

@Flacon, POST로 리디렉션을 제한하면 신체 상해를 예방할 수 있다는 증거가 필요합니다. 먼저 내 데이터로 앱을 신뢰해야하므로 데이터가 있으면 원하는대로 앱을 사용할 수 있습니다. 그리고 리디렉션 요청이 POST 요청보다 더 취약하다고 생각하지 않습니다.
b01

3

GET (및 몇 가지 다른 방법)은 http 사양 ( RFC 2616 ) 에서 'SAFE'로 정의됩니다 .

9.1.1 안전한 방법

구현자는 소프트웨어가 인터넷을 통한 상호 작용에서 사용자를 나타내며 사용자가 자신이나 다른 사람에게 예기치 않은 의미를 가질 수있는 조치를 사용자가 인식 할 수 있도록주의해야합니다.

특히, GET 및 HEAD 메소드는 검색 이외의 조치를 취하지 않아야한다는 협약이 확립되었습니다. 이 방법들은 "안전한"것으로 간주되어야합니다. 이를 통해 사용자 에이전트는 POST, PUT 및 DELETE와 같은 다른 방법을 특별한 방식으로 표현할 수 있으므로 안전하지 않은 조치가 요청되고 있다는 사실을 사용자에게 알릴 수 있습니다.

당연히 GET 요청을 수행 한 결과 서버가 부작용을 일으키지 않도록 보장 할 수는 없습니다. 실제로 일부 동적 자원은 해당 기능을 고려합니다. 여기서 중요한 차이점은 사용자가 부작용을 요청하지 않았으므로 책임을 질 수 없다는 것입니다.

즉, GET 요청은 사용자가보고 싶지 않은 것을 보는 것 이상으로 사용자에게 심각한 영향을 미치지 않아야하지만 POST 요청은 해당 사용자 나 다른 사람에게 중요한 리소스를 변경할 수 있습니다.

JavaScript로 변경되었지만 전통적으로 다른 사용자 인터페이스가있었습니다. 사용자는 링크를 클릭하여 GET 요청을 트리거 할 수 있지만 POST 요청을 트리거하려면 양식을 작성해야합니다. 필자는 HTTP 디자이너가 안전한 방법과 안전하지 않은 방법을 구별하기를 원한다고 생각합니다.

또한 POST로 리디렉션해야한다고 생각하지 않습니다. 서버 측 코드 내에서 함수를 호출하거나 다른 서버에서 발생해야하는 경우 브라우저의 URL이 포함 된 리디렉션을 서버에 POST로 보내는 대신 수행해야 할 모든 작업을 수행 할 수 있습니다. 사용자의 프록시처럼 작동하여 해당 서버 자체에 요청할 수 있습니다.

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