답변:
POST 요청을 할 때는 요청 본문을 구성하는 데이터를 어떤 방식 으로든 인코딩해야합니다.
HTML 양식은 세 가지 인코딩 방법을 제공합니다.
application/x-www-form-urlencoded
(기본)multipart/form-data
text/plain
추가에 대한 작업이 완료 application/json
되었지만 포기되었습니다.
(HTML 양식 제출 이외의 다른 방법을 사용하여 생성 된 HTTP 요청으로 다른 인코딩이 가능합니다. JSON은 웹 서비스에 사용되는 일반적인 형식이며 일부는 여전히 SOAP를 사용합니다.)
형식의 세부 사항은 대부분의 개발자에게 중요하지 않습니다. 중요한 점은 다음과 같습니다.
text/plain
.클라이언트 측 코드를 작성하는 경우 :
multipart/form-data
양식에 <input type="file">
요소가 포함 된 경우 사용multipart/form-data
또는 application/x-www-form-urlencoded
하지만 application/x-www-form-urlencoded
더 효율적입니다서버 측 코드를 작성하는 경우 :
Perl CGI->param
이나 PHP의 $_POST
superglobal에 의해 노출 된 것과 같은 대부분 은 여러분의 차이점을 처리 할 것입니다. 서버가 수신 한 원시 입력을 구문 분석하려고하지 마십시오.
때로는 두 형식을 모두 처리 할 수없는 라이브러리가 있습니다. 양식 데이터를 처리하기 위해 Node.js에서 가장 많이 사용되는 라이브러리는 본문 파서 이며 여러 부분으로 된 요청을 처리 할 수 없습니다.
원시 데이터를 구문 분석하거나 생성하기 위해 라이브러리를 작성 (또는 디버깅)하는 경우 형식에 대해 걱정해야합니다. 관심을 끌기 위해 그것에 대해 알고 싶을 수도 있습니다.
application/x-www-form-urlencoded
URL 끝에있는 검색어 문자열과 거의 동일합니다.
multipart/form-data
훨씬 더 복잡하지만 전체 파일을 데이터에 포함시킬 수 있습니다. 결과의 예는 HTML 4 사양 에서 찾을 수 있습니다 .
text/plain
는 HTML 5에 의해 도입되었으며 스펙 에서 디버깅하는 경우에만 유용합니다 . 컴퓨터에서 안정적으로 해석 할 수 없습니다. 도구와 결합 된 다른 도구 ( 대부분의 브라우저의 개발자 도구에 있는 네트워크 패널 등 )가 더 낫다고 주장합니다 그에 대한).
언제 사용해야합니까
Quentin의 대답은 옳습니다. multipart/form-data
양식에 파일 업로드가 포함되어 있으면 사용 하고 application/x-www-form-urlencoded
그렇지 않으면 생략 enctype
합니다.
할거다:
다음과 같은 세 가지 가능성 이 있습니다 enctype
.
application/x-www-form-urlencoded
multipart/form-data
(사양은 RFC7578 을 가리킴 )text/plain
. 이것은 "컴퓨터로 확실하게 해석 할 수 없음"이므로 프로덕션 환경에서는 절대 사용해서는 안되며 더 이상 조사하지 않을 것입니다.각 방법의 예를 보면 각 방법의 작동 방식과 사용 방법이 명확 해집니다.
다음을 사용하여 예제를 생성 할 수 있습니다.
nc -l
또는 ECHO 서버 : GET / POST 요청을 승인하는 HTTP 테스트 서버양식을 최소 .html
파일 로 저장하십시오 .
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>upload</title>
</head>
<body>
<form action="http://localhost:8000" method="post" enctype="multipart/form-data">
<p><input type="text" name="text1" value="text default">
<p><input type="text" name="text2" value="aωb">
<p><input type="file" name="file1">
<p><input type="file" name="file2">
<p><input type="file" name="file3">
<p><button type="submit">Submit</button>
</form>
</body>
</html>
우리의 기본 텍스트 값 설정 aωb
수단 aωb
때문 ω
이다 U+03C9
바이트있는, 61 CF 89 62
UTF-8인치
업로드 할 파일을 작성하십시오.
echo 'Content of a.txt.' > a.txt
echo '<!DOCTYPE html><title>Content of a.html.</title>' > a.html
# Binary file containing 4 bytes: 'a', 1, 2 and 'b'.
printf 'a\xCF\x89b' > binary
작은 에코 서버를 실행하십시오.
while true; do printf '' | nc -l 8000 localhost; done
브라우저에서 HTML을 열고 파일을 선택한 후 제출을 클릭하고 터미널을 확인하십시오.
nc
받은 요청을 인쇄합니다.
테스트 대상 : Ubuntu 14.04.3, nc
BSD 1.105, Firefox 40.
Firefox가 보냈습니다 :
POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"
text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text2"
aωb
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain
Content of a.txt.
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html
<!DOCTYPE html><title>Content of a.html.</title>
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file3"; filename="binary"
Content-Type: application/octet-stream
aωb
-----------------------------735323031399963166993862150--
이진 파일 및 텍스트 필드의 경우 바이트 61 CF 89 62
( aωb
UTF-8)가 문자 그대로 전송됩니다. nc -l localhost 8000 | hd
를 사용하여 바이트를 확인할 수 있습니다 .
61 CF 89 62
전송되었습니다 ( 61
== 'a'및 62
== 'b').
따라서 다음 사항이 분명합니다.
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
컨텐츠 유형을로 설정하고 multipart/form-data
필드가 주어진 boundary
문자열 로 구분된다고 말합니다 .
그러나 다음 사항에 유의하십시오.
boundary=---------------------------735323031399963166993862150
--
실제 장벽보다 덜 두껍 습니다.
-----------------------------735323031399963166993862150
표준에 경계가 두 개의 대시로 시작해야하기 때문 --
입니다. 다른 대시는 Firefox가 임의의 경계를 구현하기로 선택한 방식으로 보입니다. RFC 7578은 다음 두 개의 대시 --
가 필요하다고 분명히 언급 합니다.
4.1. multipart / form-data의 "경계"매개 변수
다른 다중 부품 유형과 마찬가지로 부품은 CRLF, "-"및 "boundary"매개 변수의 값을 사용하여 구성된 경계 구분 기호로 구분됩니다.
모든 필드는 데이터 전에 일부 서브 헤더를 가져옵니다 Content-Disposition: form-data;
필드 name
의 filename
데이터 다음을.
서버는 다음 경계 문자열까지 데이터를 읽습니다. 브라우저는 어떤 필드에도 나타나지 않는 경계를 선택해야하므로 요청마다 경계가 다를 수 있습니다.
고유 경계가 있기 때문에 데이터 인코딩이 필요하지 않습니다. 이진 데이터는 그대로 전송됩니다.
TODO : 최적의 경계 크기 ( log(N)
내기)와 그것을 찾는 알고리즘의 이름 / 실행 시간은 얼마입니까? 질문 : /cs/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences
Content-Type
브라우저에 의해 자동으로 결정됩니다.
정확하게 결정된 방법 : 업로드 된 파일의 MIME 유형은 브라우저에 의해 어떻게 결정됩니까?
이제 변경 enctype
에를 application/x-www-form-urlencoded
, 브라우저, 그리고 다시 보내기를 다시로드합니다.
Firefox가 보냈습니다 :
POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary
분명히 파일 데이터는 전송되지 않았고 기본 이름 만 전송되었습니다. 따라서 파일에는 사용할 수 없습니다.
텍스트 필드에 관해서는, 우리는 같은 것을 보통의 인쇄 가능한 문자를 참조 a
와 b
같은 인쇄 할 수없는 것들 동안 1 바이트에 보내졌다 0xCF
하고 0x89
위로했다 3 바이트 각 : %CF%89
!
파일 업로드는 종종 인쇄 할 수없는 많은 문자 (예 : 이미지)를 포함하지만 텍스트 형식은 거의 없습니다.
예제에서 우리는 다음을 보았습니다.
multipart/form-data
: 메시지에 몇 바이트의 경계 오버 헤드를 추가하고 계산하는 데 시간이 걸리지 만 각 바이트를 1 바이트로 보냅니다.
application/x-www-form-urlencoded
: 필드 당 단일 바이트 경계 ( &
)를 갖지만 인쇄 할 수없는 모든 문자에 대해 3 배 의 선형 오버 헤드 계수를 추가합니다 .
따라서로 파일을 보낼 수 있어도 application/x-www-form-urlencoded
비효율적이므로 원하지 않습니다.
그러나 텍스트 필드에있는 인쇄 가능한 문자의 경우 중요하지 않으며 오버 헤드가 적으므로 그냥 사용합니다.
%CF
긴 3 바이트이다 %
, C
그리고 F
그 사람이 읽을 수있는 만드는 :-) 이야기.
nc
모두 수락하지 않습니다 -l
과 -p
동시에 인수를. 그러나 이것은 나를 위해 작동합니다 while true; do printf '' | nc -l 8000; done
.
Content-Type
가 두 개의 하이픈 ( --
)이 적다는 것입니다. 즉, 실제로 메시지 본문에서 경계를 사용할 때는 접두사를 접두어로 사용해야합니다 --
. 또한 마지막 경계에는 접미사가 붙어야 --
하지만 알아 채기 쉽습니다. 참조 stackoverflow.com/questions/3508252/...
enctype='multipart/form-data
POST를 통해 파일을 보낼 수있는 인코딩 유형입니다 . 간단히 말해서이 인코딩이 없으면 파일을 POST를 통해 보낼 수 없습니다 .
사용자가 양식을 통해 파일을 업로드 할 수있게하려면이 enctype 을 사용해야합니다 .
multipart/form-data
이진이 아닌 파일을 보내는 데 사용할 수는 있지만 비효율적입니다. application/x-www-form-urlencoded
이진이 아닌 데이터를 보내는 올바른 방법을 사용 하는 것이지만 이진이 아닌 파일에 대한 경험이 많은 사람이 나를 수정해야 할 수도 있습니다.
multipart/form-data
파일 전송 에 사용하는 주요 이점 은 프런트 엔드 및 백엔드에서 자동으로 작동한다는 것입니다. 특별한 취급이 필요하지 않습니다. 텍스트 만 포함하더라도 모든 파일은 이진 파일입니다. application/x-www-form-urlencoded
첨부 파일없이 양식을 POST하는 표준 방법입니다. multipart/form-data
첨부 파일이있는 양식을 POST하는 표준 방법입니다. ( 서버와 클라이언트 사이의 통신에 일반적으로 사용되는 application/json
and와 같은 수많은 다른 인코딩도 있습니다 application/json-patch+json
.)
multipart/form-data
. 당신이 할 수없는 일은 JavaScript없이 일반적인 HTML 양식 제출을 사용하는 것입니다. 사용할 양식을 설정하는 multipart/form-data
것은 JavaScript를 사용하지 않고 파일을 POST 할 수 있도록 HTML이 제공 하는 유일한 메커니즘입니다 . 나는 이것이 대답에서 충분히 명확하지 않다고 느끼고 순진한 독자는 파일을 보낼 수 없다는 것이 HTTPmultipart/form-data
의 한계 라고 생각할 수도 있습니다 . 그렇지 않습니다.
양식을 제출할 때 HTTP 프로토콜을 통해 TCP / IP 프로토콜 메시지 구조로 올바르게 엔벨로프 된 메시지를 네트워크에 보내도록 브라우저에 지시하십시오. HTML 페이지에는 <form>
s 를 사용하여 서버로 데이터를 보내는 방법이 있습니다.
양식이 제출되면 HTTP 요청이 작성되어 서버로 전송됩니다. 메시지에는 양식의 필드 이름과 사용자가 입력 한 값이 포함됩니다. 이 전송은 POST
또는 GET
HTTP 메소드로 발생할 수 있습니다 .
POST
브라우저에 HTTP 메시지를 작성하고 모든 내용을 메시지 본문에 넣도록 지시합니다 (보다 안전하고 유연하게 작업을 수행하는 매우 유용한 방법).GET
querystring에 양식 데이터를 제출합니다 . 데이터 표현과 길이에 대한 제약이 있습니다.메소드를 enctype
사용할 때만 속성 이 의미가 POST
있습니다. 지정된 경우 특정 방식으로 컨텐츠를 인코딩하여 양식을 보내도록 브라우저에 지시합니다. 에서 MDN - 양식에 enctype :
method 속성의 값이 post 인 경우, enctype은 서버에 양식을 제출하는 데 사용되는 컨텐츠의 MIME 유형입니다.
application/x-www-form-urlencoded
: 이것이 기본값입니다. 양식이 전송되면 모든 이름과 값이 수집되고 최종 문자열에서 URL 인코딩 이 수행됩니다.multipart/form-data
: 문자가 인코딩되지 않습니다. 양식에 파일 업로드 컨트롤이있는 경우 중요합니다. 파일 바이너리를 보내려고하면 비트 스트림이 변경되지 않습니다.text/plain
: 공백이 변환되지만 더 이상 인코딩이 수행되지 않습니다.양식을 제출할 때 RFC 7578 섹션 7 : 다중 파트 양식 데이터-보안 고려 사항에 명시된대로 일부 보안 문제가 발생할 수 있습니다 .
모든 양식 처리 소프트웨어는
기밀 또는 개인
식별 정보를 포함하기 때문에 사용자가 제공 한 양식 데이터 를 민감하게 처리해야 합니다. 웹 브라우저에는 "자동 채우기"기능이 널리 사용됩니다. 이는 무해한 작업을
완료 할 때 무의식적으로 기밀 정보를 보내도록 사용자를 속이는 데 사용될 수 있습니다
. multipart / form-data는
무결성 검사, 기밀 유지, 사용자
혼동 방지 또는 기타 보안 기능을 위한 기능 을 제공하지 않습니다 . 이러한 문제는
양식 작성 및 양식 데이터 해석 응용 프로그램에서 해결 해야합니다 .양식을 수신하여 처리하는 응용 프로그램은 요청하지 않은 요청 양식 처리 사이트로 데이터를 다시 보내지 않도록주의해야합니다.
수신자의 파일 공간
에있는 파일을 실수로 덮어 쓰지 않도록 Content- Disposition 헤더 필드 의 파일 이름을 해석 할 때 중요
합니다.
이는 개발자이고 서버가 사용자가 제출 한 양식을 처리하여 중요한 정보가 포함되어있을 경우에 중요합니다.
enctype
. 나는 그것이 multipart/form-data
RFC 에서 온 것임을 알고 있지만 그럼에도 불구하고 데이터가 application/x-www-form-urlencoded
또는 로 전송되는지 여부에 완전히 직교하는 양식을 제출하는 것에 대한 임의의 보안 고려 사항 multipart/form-data
입니다.
파일 내용을 양식을 사용하여 URL 매개 변수에 넣을 수 없으므로 method 속성을 POST로 설정하십시오.
enctype의 값을 multipart / form-data로 설정하십시오. 데이터는 여러 파일로 분할되므로 각 파일에 대해 하나씩 추가 될 수 있으며 양식 본문의 텍스트에 대해서는 하나씩 있습니다.
POST
양식을 통해 파일을 제출하기에 충분 multipart/form-data
하고 모호한 방식으로 추가하는 것이 보너스 라는 것을 의미합니다 . 그렇지 않습니다. 대부분의 파일은 반드시을 사용해야합니다 multipart/form-data
.
<head>
와 <body>
관련이 없으며 혼란 스럽습니다.
enctype 속성은 양식 데이터를 서버에 제출할 때 양식 데이터를 인코딩하는 방법을 지정합니다.
enctype 속성은 method = "post"인 경우에만 사용할 수 있습니다.
인코딩 된 문자가 없습니다. 파일 업로드 제어가있는 양식을 사용하는 경우이 값이 필요합니다.
에서 W3 스쿨
multipart/form-data
. 또한 불분명합니다. "문자가 인코딩되지 않음"이라는 문장의 의미는 무엇입니까? -1.