중복 HTTP GET 쿼리 키의 권한있는 위치


137

HTTP GET 쿼리 문자열 중복 필드의 동작에 대한 권위있는 정보를 찾는 데 문제가 있습니다.

http://example.com/page?field=foo&field=bar 

특히 주문이 유지되는지 여부. 대부분의 웹 지향 언어는 키 "필드"와 관련된 foo와 bar를 포함하는 배열을 생성하지만이 시점에 대해 권위있는 진술이 있는지 (예 : RFC에) 알고 싶습니다. RFC 3986 에는 3.4. Query키 = 값 쌍을 참조 하는 섹션이 있지만 순서를 해석하고 필드를 복제하는 방법에 대해서는 언급되어 있지 않습니다. RFC의 범위가 아닌 백엔드에 의존하기 때문에 이것은 의미가 있습니다 ...

사실상의 표준이 존재하지만 호기심으로 인해 권위있는 소스를보고 싶습니다.


그것에 대해 궁금했습니다. 다른 것은 쿼리 문자열의 매개 변수를 POST 본문의 매개 변수와 병합하는 사양입니다.
Thilo

사람들은 코드 목장에서 주문 보장이 없다고 말합니다. 그러나 그 스레드는 오래되었고 아무도 그것을 백업하지 않습니다 : coderanch.com/t/357197/Servlets/java/getParameterValues-order
Thilo

1
쿼리 문자열의 순서를 유지하는 서버 외에도 브라우저가 DOM (또는 다른 고정 된) 순서로 쿼리를 보내는 것에 대한 질문도 있습니다.
Thilo November

답변:


112

이에 대한 사양이 없습니다 . 당신이 원하는 것을 할 수 있습니다.

일반적인 접근 방식에는 첫 번째, 마지막, 모든 배열, 쉼표와 함께 쉼표가 있습니다.

원시 요청이 다음과 같다고 가정하십시오.

GET /blog/posts?tag=ruby&tag=rails HTTP/1.1
Host: example.com

그런 다음 request.query['tag']언어 나 프레임 워크에 따라 산출해야하는 다양한 옵션이 있습니다 .

request.query['tag'] => 'ruby'
request.query['tag'] => 'rails'
request.query['tag'] => ['ruby', 'rails']
request.query['tag'] => 'ruby,rails'

12
더 중요한 것은 [ 'rails', 'ruby'] (다른 순서) 옵션도 있습니다.
Thilo

2
분명히 많은 일을 할 수 있습니다.
yfeldblum '11

7
.NET은 배열로 당신을 줄 것입니다 (필자는 테스트했을 때 순서에 신경 쓰지 않았습니다) .PHP는 항상 마지막 값을 제공하고 Java (적어도 Java를 기반으로 작업 한 시스템)는 항상 첫 번째 값을 제공합니다. stackoverflow.com/questions/1809494/…
SimonSimCity 7

17
이것은 HTTP 매개 변수 오염라는 공격을 기반으로하며 OWASP에 의해 분석되었습니다 owasp.org/images/b/ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf 9 페이지에서 당신은 20 시스템의 목록과 처리하는 방법에 대한 설명을 찾을 수 있습니다 이 문제.
SimonSimCity

1
@SimonSimCity와 더불어 PHP는 매개 변수 이름에 선택적 색인이있는 대괄호를 추가하면 실제로 배열을 만듭니다.
Martin Ender

14

PHP (최소 버전 4.4.4 이상)에서는 다음과 같이 작동 함을 확인할 수 있습니다.

GET /blog/posts?tag=ruby&tag=rails HTTP/1.1
Host: example.com

결과 :

request.query['tag'] => 'rails'

그러나

GET /blog/posts?tag[]=ruby&tag[]=rails HTTP/1.1
Host: example.com

결과 :

request.query['tag'] => ['ruby', 'rails']

이 동작은 GET 및 POST 데이터에서 동일합니다.


1
[]접미사는 정말 이상한 행동처럼 보인다,하지만 당신은 jQuery의를 통해 인수로 배열을 전송하려고하면 .ajax(), 그것은 자동으로 동일한 방법으로 당신을 위해 그들을 추가 할 것입니다. 이것은 PHP 사용자의 이익으로 보입니다.
Ian Clark

4
@IanClark PHP 코더에게는 직관적입니다. 일반 PHP에서는 $foo[] = 1배열에 추가됩니다. 장고 (Python)도 마찬가지입니다.
Izkata

Apache Tomcat에서 쉼표로 연결된 문자열을 반환하는지 확인할 수 있습니다.
Gaurav Ojha

8

yfeldblum의 답변은 완벽합니다.

최근에 주목 한 다섯 번째 동작에 대한 참고 사항 : Windows Phone 에서 중복 쿼리 키로 URI를 사용하여 응용 프로그램을 열면 NavigationFailed가 발생합니다.

System.ArgumentException : 같은 키를 가진 항목이 이미 추가되었습니다.

범인은 System.Windows.Navigation.UriParsingHelper.InternalUriParseQueryStringToDictionary(Uri uri, Boolean decodeResults)입니다.

따라서 시스템이 원하는 방식으로 처리하지 못하게하여 금지합니다. 자신 만의 형식 (CSV, JSON, XML 등)과 uri-escape-it를 선택할 수있는 유일한 솔루션이 있습니다.


2
그것은 디자인 선택이 아니라 그 기능의 내부 버그처럼 보입니다. 아마도 함수는 작성중인 사전에서 중복 키를 확인하지 않습니다. 물론 사전에는 고유 키가 필요합니다.
gligoran

1
따라서이 상황에서 서버가 아닌 클라이언트 브라우저 에서 오류가 발생합니까? 버그 인 것 같습니다. 이 버그가 오늘날에도 여전히 존재하는지 궁금합니다.
존 슈나이더

1
@JonSchneider 예, 클라이언트는 NavigationFailed그러한 URI를 던지고 있습니다. 그러나 용서하십시오.이 게시물 한 달 후 Windows (전화) 개발을 중단하고 macOS (iOS)로 옮겼으므로 더 이상이 문제를 추적하는 데 도움을 줄 수 없습니다.
Cœur

5

프레임 워크의 대부분 (모두?)은 보증을 제공하지 않으므로 임의 순서로 리턴된다고 가정하십시오.

항상 가장 안전한 방법을 사용하십시오.

예를 들어, java HttpServlet 인터페이스 : ServletRequest.html # getParameterValues

getParameterMap 메소드 에서도 매개 변수 순서에 대한 언급은 생략합니다 (java.util.Map 반복자의 순서도 신뢰할 수 없음).


3

일반적으로 다음과 같은 중복 매개 변수 값

http://example.com/page?field=foo&field=bar

배열 인 단일 queryString 매개 변수가됩니다.

field[0]=='foo'
field[1]=='bar'

ASP, ASP.NET 및 PHP4에서이 동작을 보았습니다.


정확히, 이것은 사실상의 표준이지만, 내가 볼 때까지 그것에 대한 권위있는 결정은 없습니다. 나는 이것이 사실이라고 생각하지 않기 때문에 그것을 찾지 못하는 것입니다.
Stefano Borini

2
예, 아마 모든 사람이 그 행동을 보았습니다. 문제는 그것이 실제로 어딘가에 지정되어 있는지였습니다.
Thilo November

-1

나는 같은 질문을했다. 쿼리를 구문 분석하고 문자열 화하기 위해 자바 스크립트 함수를 작성 중입니다. 쿼리 문자열에 중복 이름이나 x [] = 1 & x [] = 2와 같이 대괄호가있는 이름이 있는지 여부는 알 수 없지만 일부 언어는 이러한 형식을 지원합니다.

그러나 Chrome과 Firefox에는 이름이 지정된 새로운 클래스가 URLSeachParams있으며 가장 간단한 형식 만 지원합니다 name=value. 쿼리 문자열에 중복 이름이있는 경우 첫 번째 이름 만 반환하는 get방법입니다 URLSearchParams.

따라서 개인적으로, 가장 단순하고 중복되는 이름 URL은 미래에 훨씬 더 안전합니다.


1
쿼리 문자열에 중복 이름이 있으면 URLSearchParams의 get 메소드는 첫 번째 이름 만 리턴합니다. 이것은 정확하지 않습니다 :URLSearchParams.getAll('x')
Blaise

@Blaise 너무 감사합니다, 나는 전에 기능을 오해했습니다.
LCB 2019
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.