HTTP POST 요청에서 매개 변수는 어떻게 전송됩니까?


1475

HTTP GET 요청에서 매개 변수는 쿼리 문자열 로 전송됩니다 .

http://example.com/page ? parameter = value & also = another

HTTP POST 요청에서 매개 변수는 URI와 함께 전송되지 않습니다.

가치는 어디에 있습니까? 요청 헤더에? 요청 본문에서? 그것은 어떻게 생겼습니까?

답변:


1252

값은 컨텐츠 유형이 지정하는 형식으로 요청 본문에 전송됩니다.

일반적으로 컨텐츠 유형은 application/x-www-form-urlencoded이므로 요청 본문은 쿼리 문자열과 동일한 형식을 사용합니다.

parameter=value&also=another

양식에서 파일 업로드를 사용하는 multipart/form-data경우 다른 형식 의 인코딩을 대신 사용하십시오 . 더 복잡하지만 일반적으로 모양을 신경 쓸 필요가 없으므로 예제를 보여주지 않지만 그것이 존재한다는 것을 아는 것이 좋습니다.


25
파일 업로드가 다르다는 것을 잊었습니다 (+ 1 / 수락). 귀하의 답변은 충분하지만에 대한 자세한 정보가 있으면 더 좋을 것입니다 multipart/form-data. 관심있는 사람들을 위해 여기에 대한 질문이 있습니다 .
Camilo Martin

73
참고 : 본문은 빈 줄 하나만으로 머리글에서 분리됩니다 .
Gab 是 好人

2
우리는 HTTPBody에 무엇을 배치했는지 설명했지만 HTTPHeader에 무엇을 배치 / 작성합니까? 어떤 목적으로 사용됩니까?
Honey

4
@Honey : 게시물의 HTTP 헤더는 가져 오기의 HTTP 헤더처럼 보이지만 GET 대신 동사 POST와 요청에 내용 (본문)이있는 경우 내용 유형 값 (및 선택적 내용 길이 값)이 있습니다. 모든 유형의 요청에는 헤더가 있으며 일부 유형에는 본문도 있습니다.
구파

4
@KennethWorden 아니요, 메소드 중 하나가 JSON을 올바르게 전송합니다. 그러나 인코딩 된 형식으로 multipart/form-data또는 요청 생성을 담당하는 경우 json 파일을 업로드 할 수 있습니다. 컨텐츠 유형을 변경 application/json하고 json 텍스트를 http 본문에 직접 붙여 넣기
Cholthi Paul Ttiopic

428

내용은 HTTP 헤더 뒤에 있습니다. HTTP POST의 형식은 HTTP 헤더, 빈 줄, 요청 본문을 갖는 것입니다. POST 변수는 본문에 키-값 쌍으로 저장됩니다.

아래에 표시된 HTTP Post의 원시 컨텐츠에서이를 확인할 수 있습니다.

POST /path/script.cgi HTTP/1.0
From: frog@jmarshall.com
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32

home=Cosby&favorite+flavor=flies

Fiddler 와 같은 도구를 사용하여이를 확인할 수 있습니다.이 도구 는 원시 HTTP 요청 및 응답 페이로드가 회선을 통해 전송되는 것을 보는 데 사용할 수 있습니다.


39
콘텐츠 유형이 application/x-www-form-urlencoded인 경우에만 , 항상 그런 것은 아닙니다.
Guffa

@ Camilo Martin .... [+1] 큰 질문 및 @ Joe Alfano .... [+1] 큰 대답 ....... POST 요청에 대한 명확한 아이디어를 얻었습니다 .... 그러나 이미지에 키, 값 쌍의 데이터 정보가 함께 제공되면 ..... POST의 구조는 어떻게 생겼습니까?
Devrath

9
@ 조, 이제 왜 From거기 에 헤더가 있습니까?
Pacerier

@ 조, 나는 From헤더 의 무작위 포함을 좋아합니다 . IMO 418 HTTP 상태 코드가 있습니다.
Tom Howard

사용자 및 비밀번호 인증을 어떻게 추가합니까?
m4l490n

376

짧은 답변 : POST 요청에서 값은 요청의 "본문"으로 전송됩니다. 웹 양식을 사용하면 미디어 유형이 application/x-www-form-urlencoded또는로 전송 될 가능성이 높습니다 multipart/form-data. 언어 또는 일반적으로 요청 "옳은 일을 ™"할과 (같은 쉽게 쉽게 디코딩 값에 대한 액세스를 제공 핸들 웹 요청에 디자인 된 프레임 워크 프로그래밍 $_REQUEST또는 $_POSTPHP에서, 또는 cgi.FieldStorage(), flask.request.form파이썬을).


이제 차이를 이해하는 데 도움이 될 수있는 약간의 digress를 해봅시다;)

GETPOST요청 의 차이점 은 크게 의미가 있습니다. 그것들은 또한 다르게 "사용"되며, 이는 값이 전달되는 방식의 차이를 설명합니다.

GET ( 관련 RFC 섹션 )

GET요청을 실행할 때 서버에 하나 또는 일련의 엔티티를 요청합니다. 클라이언트가 결과를 필터링 할 수 있도록 URL의 "쿼리 문자열"을 사용할 수 있습니다. 쿼리 문자열은의 다음 부분 ?입니다. 이것은 URI 구문의 일부입니다 .

따라서 애플리케이션 코드 ( 요청 을 받는 부분)의 관점 에서 이러한 값에 액세스하려면 URI 쿼리 파트를 검사해야합니다.

키와 값은 URI의 일부입니다. 브라우저 URI 길이에 제한을 둘 수 있습니다 . HTTP 표준은 제한이 없다고 명시하고 있습니다. 그러나이 글을 쓰는 시점에서 대부분의 브라우저 URI를 제한합니다 (특정한 값은 없습니다). 서버에 새로운 정보를 제출하는 데 GET요청을 사용해서는 안됩니다 . 특히 더 큰 문서는 아닙니다. 당신이 사용해야하는 곳이다 POSTPUT.

POST ( 관련 RFC 섹션 )

POST요청을 실행할 때 클라이언트는 실제로 새 문서 를 원격 호스트에 제출 합니다. 따라서 쿼리 문자열은 (의미 적으로) 의미가 없습니다. 애플리케이션 코드에서 액세스 할 수없는 이유가 여기에 있습니다.

POST좀 더 복잡한 (및 인 방법 보다 유연)

POST 요청을 수신 할 때는 항상 "페이로드"또는 HTTP 용어 인 메시지 본문을 기대해야합니다 . 메시지 본문 자체에는 표준 이 없기 때문에 꽤 쓸모가 없습니다 (어쩌면 응용 프로그램 / octet-stream?). 본문 형식은 Content-Type헤더 로 정의됩니다 . FORM와 함께 HTML 요소를 사용할 때 method="POST"일반적으로 application/x-www-form-urlencoded입니다. 또 다른 매우 일반적인 유형은파일 업로드를 사용 하는 경우 multipart / form-data 입니다. 그러나 이것은 무엇이든text/plain , 이상 application/json또는 심지어 관습에 이르기까지 다양 할 수 있습니다 application/octet-stream.

어쨌든 응용 프로그램에서 처리 할 수없는 POST요청이 있으면 status-code를Content-Type 반환해야 415합니다 .

대부분의 프로그래밍 언어 (및 / 또는 웹 프레임 워크)는 메시지 본문을 가장 일반적인 유형 (예 application/x-www-form-urlencoded: multipart/form-data또는 application/json)으로 디코드 / 인코딩하는 방법을 제공합니다 . 그래서 쉽습니다. 사용자 정의 유형은 잠재적으로 약간 더 많은 작업이 필요합니다.

표준 HTML 형식으로 인코딩 된 문서를 예로 사용하면 응용 프로그램은 다음 단계를 수행해야합니다.

  1. Content-Type필드를 읽으십시오
  2. 값이 지원되는 미디어 유형 중 하나가 아닌 경우 415 상태 코드
  3. 그렇지 않으면 메시지 본문에서 값을 디코딩하십시오.

다시 말하지만, PHP와 같은 언어 나 다른 인기있는 언어의 웹 프레임 워크가이를 처리 할 것입니다. 이것에 대한 예외는415 오류입니다. 어떤 프레임 워크도 애플리케이션이 지원하거나 지원하지 않는 컨텐츠 유형을 예측할 수 없습니다. 이것은 당신에게 달려 있습니다.

PUT ( 관련 RFC 섹션 )

PUT요청이 꽤 많이와 동일한 방법으로 처리됩니다 POST요청. 가장 큰 차이점은 POST요청으로 인해 서버가 새 리소스를 만드는 방법을 결정하게하는 것입니다. 역사적으로 (현재는 사용되지 않는 RFC2616부터 요청이 전송 된 URI의 "하위"(하위)로서 새로운 자원을 작성했습니다).

PUT달리 요청은 정확히 "예금"리소스하도록되어 에서 그 URI, 및과 정확히 콘텐츠. 그 이상도 이하도 아닌. 아이디어는 클라이언트 가 "퍼팅"하기 전에 전체 리소스를 만들어야 할 책임 이 있다는 것입니다. 서버는 주어진 URL에서 그대로 받아 들여야합니다 .

결과적으로 POST요청은 일반적으로 기존 자원 을 대체 하는 데 사용되지 않습니다 . PUT요청은 할 모두 만들 수 있습니다 교체합니다.

사이드 노트

원격에 추가 데이터를 전송하는 데 사용할 수있는 " 경로 매개 변수 " 도 있지만 너무 드물기 때문에 여기서 자세히 설명하지 않습니다. 그러나 참고로 RFC에서 발췌 한 내용은 다음과 같습니다.

계층 적 경로의 도트 세그먼트 외에도 경로 세그먼트는 일반 구문에 의해 불투명 한 것으로 간주됩니다. URI 생성 응용 프로그램은 종종 세그먼트에 허용 된 예약 문자를 사용하여 체계 별 또는 역 참조 처리기 별 하위 구성 요소를 구분합니다. 예를 들어 세미콜론 ( ";")과 같음 ( "=") 예약 문자는 종종 해당 세그먼트에 적용 가능한 매개 변수와 매개 변수 값을 구분하는 데 사용됩니다. 쉼표 ( ",") 예약 문자는 종종 유사한 목적으로 사용됩니다. 예를 들어, 하나의 URI 생성자는 "name"의 버전 1.1에 대한 참조를 나타 내기 위해 "name; v = 1.1"과 같은 세그먼트를 사용할 수있는 반면, 다른 하나는 "name, 1.1"과 같은 세그먼트를 사용하여 동일한 것을 나타낼 수 있습니다. 매개 변수 유형은 스킴 별 의미론으로 정의 될 수 있습니다.


1
나는 약간의 탄젠트에 실제로 갔다. 대답의 맨 위에 "tl; dr"을 추가하여 명확하게해야합니다.
exhuma

또한 방금 RFC2616 대신 RFC7231을 참조하도록 편집했습니다. 업데이트 된 링크와 별도로이 답변의 주요 차이점은 "PUT"섹션에 있습니다.
exhuma

PUT이 dem 등원이기 때문에 POST와 다르게 처리되었다고 생각 했습니까? stackoverflow.com/questions/611906/…
rogerdpack

1
@rogerdpack 잘못이 아니에요. 당신이에서 두 번째 단락 읽으면 PUT부분을, 당신은 것을 볼 수 있다 나무 등. POST대조적으로, 정의 상으로는 할 수 없습니다. POST항상 새로운 자원을 만듭니다. PUT동일한 자원이 존재하면이를 대체하십시오. 따라서 POST10 번 전화 하면 10 개의 리소스가 만들어집니다. PUT10 번 전화하면 하나만 생성됩니다. 그 질문에 대답합니까?
exhuma

59

브라우저 URL 표시 줄에 직접 입력 할 수 없습니다.

예를 들어 Live HTTP 헤더 를 사용하여 인터넷에서 POST 데이터가 전송되는 방식을 볼 수 있습니다 . 결과는 다음과 같습니다

http://127.0.0.1/pass.php
POST /pass.php HTTP/1.1

Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://127.0.0.1/pass.php
Cookie: passx=87e8af376bc9d9bfec2c7c0193e6af70; PHPSESSID=l9hk7mfh0ppqecg8gialak6gt5
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
username=zurfyx&pass=password

그것이 말하는 곳

Content-Length: 30
    username=zurfyx&pass=password

포스트 값이됩니다.


2
설명 : 여기에 Content-Length있어야 29합니까? 문자열의 실제 길이입니다 username=zurfyx&pass=password.
하마

@Hippo는 줄 바꿈 문자였습니까?
vikingsteve

@vikingsteve 무슨 말인지 알겠습니다. 따라서 콘텐츠 끝에 항상 줄 바꿈이 있다고 생각합니다.
Hippo

2
헤더는 추가 줄 바꿈으로 본문과 분리되어 있습니다.
Mára Toner

24

POST 요청의 기본 미디어 유형은 application/x-www-form-urlencoded입니다. 키-값 쌍을 인코딩하기위한 형식입니다. 키는 중복 될 수 있습니다. 각 키-값 쌍은 &문자 로 구분되며 각 키는 =문자로 값과 구분됩니다 .

예를 들면 다음과 같습니다.

Name: John Smith
Grade: 19

다음과 같이 인코딩됩니다 :

Name=John+Smith&Grade=19

이것은 HTTP 헤더 다음에 요청 본문에 배치됩니다.


1
우리는 HTTPBody에 무엇을 배치했는지 설명했지만 HTTPHeader에 무엇을 배치 / 작성합니까?
Honey

그 열쇠가 복제 될 수 있다고 언급했다면, 그 복제의 결과는 무엇입니까? 마지막 값이 자동으로 이전 값을 덮어 쓰게됩니까? 감사.
Jinghui Niu

@JinghuiNiu 키가 중복되면 배열로 구문 분석해야합니다. 이것은 매우 늦었지만 다른 사람을 도울 수 있습니다.
Hanash Yaslem '

18

HTTP POST의 양식 값은 쿼리 문자열과 같은 형식으로 요청 본문에 전송됩니다.

자세한 내용은 spec을 참조하십시오 .


5
"같은 형식"은 약간 모호합니다. 그들은 ?예를 들어 시작 합니까?
Camilo Martin

7
@PeterWooster 네,하지만 예제는 제공하지 않습니다. 이와 관련하여 "응용 프로그램의 블로그 (링크)에 질문에 대한 답변이 있습니다"라는 답변과 같습니다 .
Camilo Martin

36
@PeterWooster 필요하지는 않지만 무언가를 잊었을 때 매우 좋습니다 .Google에서 첫 번째 링크로 이동하면 명확하고 간결한 예제가 있습니다. 포괄적 인 경우에도 리프레쉬에 부적합 할 수있는 지나치게 자세한 사양. 생각해보십시오 :이 사이트에있는 대부분의 QA는 "spec / manual / API / etc (link) "로 넘어갈 수 있습니다. 유용할까요? Google 이상은 아닙니다.
Camilo Martin

2
콘텐츠 유형이 application/x-www-form-urlencoded인 경우에만 , 항상 그런 것은 아닙니다.
Guffa

3
GET 쿼리 문자열의 형식은 application / x-www-form-urlencoded의 형식과 다릅니다. 예를 들어 공백은 다르게 인코딩됩니다 (% 20 vs +). 이와 관련하여 답이 잘못되었습니다.
UnclickableCharacter

18

일부 웹 서비스에서는 요청 데이터메타 데이터 를 배치해야합니다. 별도로 . 예를 들어, 원격 기능은 서명 된 메타 데이터 문자열이 URI에 포함되는 반면 데이터는 HTTP- 본체에 게시 될 것으로 예상 할 수 있습니다.

POST 요청은 의미 적으로 다음과 같습니다.

POST /?AuthId=YOURKEY&Action=WebServiceAction&Signature=rcLXfkPldrYm04 HTTP/1.1
Content-Type: text/tab-separated-values; charset=iso-8859-1
Content-Length: []
Host: webservices.domain.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)

name    id
John    G12N
Sarah   J87M
Bob     N33Y

이 접근 방식은 단일을 사용하여 QueryString과 Body-Post를 논리적으로 결합합니다. Content-Type 은 웹 서버에 대한 "구문 분석"인 을 합니다.

참고 : HTTP / 1.1은 왼쪽 의 (공백)과 오른쪽의 (줄 바꿈)으로 래핑 됩니다 .#32#10


의 차이 /user/john와는 /?user=john합리적으로 예상대로 나는이 걸릴 수 있도록, 단지 의미 하나 (실제로 쿼리 문자열에 대한 특별 대우를 제공하지 않는 HTTP)입니다. 그러나 "왼쪽 공간에 싸여있다"는 것은 무엇을 의미합니까? HTTP 메소드 앞에 공백이 없습니다. 포스트 바디의 빈 줄을 의미합니까?
Camilo Martin

위 코드 사이 ...Ym04와 사이에 공백 (ASCII # 32)이 HTTP/1.1있습니다. 따라서 QueryString은 동사와 프로토콜 버전 사이에 있습니다.
인터페이스 알 수 없음

1
당신의 노트는 예상치 못한 버전에 특정한 것처럼 들린다. 솔직히 거기에 공간이 있다는 것이 명백해 보입니다. 그리고 줄 바꿈은 모든 유닉스와 마찬가지로 다른 줄에도 적용됩니다.
카밀로 마틴

1
코드에서 표시 할 수없는 것을 강조했습니다. 분명해 보일 수도 있지만 때로는 그렇지 않습니다.
인터페이스 알 수 없음

요청 ?과 마찬가지로 URI와 매개 변수를 분리하여 URL의 일부로 쿼리 매개 변수를 전달할 수 있다는 것은 사실입니다 GET.
획득

8

우선, GETPOST

가져 오기 : 그것은 기본입니다 HTTP서버에 만들어지고 다음에 오는 서버와 쿼리 문자열에서 데이터를 검색하는 데 사용됩니다 요청 ?A는에서 URI고유 리소스를 검색하는 데 사용됩니다.

이것은 형식입니다

GET /someweb.asp?data=value HTTP/1.0

다음 data=value은 전달 된 쿼리 문자열 값입니다.

POST : 데이터를 서버에 안전하게 전송하는 데 사용되므로 필요한 것은 POST요청 형식입니다.

POST /somweb.aspHTTP/1.0
Host: localhost
Content-Type: application/x-www-form-urlencoded //you can put any format here
Content-Length: 11 //it depends
Name= somename

왜 POST를 통해 POST해야합니까?

에서 GET일반적으로 쿼리 문자열의 기본 URL에 추가 된 서버로 전송되는 값, 지금의이 개 결과가있다

  • GET요청은 매개 변수를 사용하여 브라우저 기록에 저장됩니다. 따라서 브라우저 기록에서 비밀번호는 암호화되지 않은 상태로 유지됩니다. 이것은 며칠 전 페이스 북에게있어 실질적인 문제였습니다.
  • 일반적으로 서버는 사용 가능한 기간에 제한 URI이 있습니다. 너무 많은 매개 변수가 전송되면414 Error - URI too long

게시 요청의 경우 필드의 데이터가 대신 본문에 추가됩니다. 요청 매개 변수의 길이가 계산되어 컨텐츠 길이의 헤더에 추가되며 중요한 데이터가 URL에 직접 추가되지 않습니다.

Google 개발자 도구의 네트워크 섹션을 사용하여 서버에 대한 요청 방법에 대한 기본 정보를 볼 수 있습니다.

당신은 항상 더 많은 값을 추가 할 수 있습니다 Request Headers같은 Cache-Control, Origin, Accept.


4
보안에 대한 가정은 HTTPS연결 컨텍스트에서만 적용됩니다 HTTP. HTTPS암호화 / 보호하지 않을 때 URL(쿼리 매개 변수 포함) 및를 모두 암호화합니다. 설명 된 문제는 많은 브라우저가를 포함 하여를 히스토리 데이터베이스에 저장한다는 사실에서 비롯 됩니다 (보통 암호화되지 않음). 따라서 민감한 항목 에는 + 만 사용하십시오 . Request BodyHTTPURIsURLsRequest BodyHTTPS
Petru Zaharia

@PetruZaharia 나는 당신의 설명에 동의합니다. 이것을 편집으로 제안 할 수 있으며 기꺼이 받아 들일 것입니다! :)
Zeeshan Adil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.