enctype = 'multipart / form-data'는 무엇을 의미합니까?


답변:


1570

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의 $_POSTsuperglobal에 의해 노출 된 것과 같은 대부분 은 여러분의 차이점을 처리 할 것입니다. 서버가 수신 한 원시 입력을 구문 분석하려고하지 마십시오.

때로는 두 형식을 모두 처리 할 수없는 라이브러리가 있습니다. 양식 데이터를 처리하기 위해 Node.js에서 가장 많이 사용되는 라이브러리는 본문 파서 이며 여러 부분으로 된 요청을 처리 할 수 ​​없습니다.


원시 데이터를 구문 분석하거나 생성하기 위해 라이브러리를 작성 (또는 디버깅)하는 경우 형식에 대해 걱정해야합니다. 관심을 끌기 위해 그것에 대해 알고 싶을 수도 있습니다.

application/x-www-form-urlencoded URL 끝에있는 검색어 문자열과 거의 동일합니다.

multipart/form-data훨씬 더 복잡하지만 전체 파일을 데이터에 포함시킬 수 있습니다. 결과의 예는 HTML 4 사양 에서 찾을 수 있습니다 .

text/plain는 HTML 5에 의해 도입되었으며 스펙 에서 디버깅하는 경우에만 유용합니다 . 컴퓨터에서 안정적으로 해석 할 수 없습니다. 도구와 결합 된 다른 도구 ( 대부분의 브라우저의 개발자 도구에 있는 네트워크 패널 등 )가 더 낫다고 주장합니다 그에 대한).


5
@Quentin 실례합니다. 모든 양식에 multipart를 사용하면 어떤 문제가 발생합니까? 파일과 함께하고 부엉이.
Webinan

12
GET 양식에는 적합하지 않으며 요청의 파일 크기가 더 큽니다.
Quentin

@Quentin은 멀티 파트 양식 데이터를 기본적으로 스트림으로 전송합니까?
Growler

enctype의 enc가 무언가를 의미합니까?
Philip Rego

1
"HTML 양식은 ENC oding 의 세 가지 방법을 제공합니다 "
Quentin

449

언제 사용해야합니까

Quentin의 대답은 옳습니다. multipart/form-data양식에 파일 업로드가 포함되어 있으면 사용 하고 application/x-www-form-urlencoded그렇지 않으면 생략 enctype합니다.

할거다:

  • HTML5 참조를 더 추가하십시오.
  • 설명 그가 양식을 제출 예와 권리

HTML5 참조

다음과 같은 세 가지 가능성 이 있습니다 enctype.

예제를 생성하는 방법

각 방법의 예를 보면 각 방법의 작동 방식과 사용 방법이 명확 해집니다.

다음을 사용하여 예제를 생성 할 수 있습니다.

양식을 최소 .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&#x03C9;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&#x03C9;b수단 aωb때문 ω이다 U+03C9바이트있는, 61 CF 89 62UTF-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, ncBSD 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ωbUTF-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;필드 namefilename데이터 다음을.

    서버는 다음 경계 문자열까지 데이터를 읽습니다. 브라우저는 어떤 필드에도 나타나지 않는 경계를 선택해야하므로 요청마다 경계가 다를 수 있습니다.

    고유 경계가 있기 때문에 데이터 인코딩이 필요하지 않습니다. 이진 데이터는 그대로 전송됩니다.

    TODO : 최적의 경계 크기 ( log(N)내기)와 그것을 찾는 알고리즘의 이름 / 실행 시간은 얼마입니까? 질문 : /cs/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences

  • Content-Type 브라우저에 의해 자동으로 결정됩니다.

    정확하게 결정된 방법 : 업로드 된 파일의 MIME 유형은 브라우저에 의해 어떻게 결정됩니까?

application / x-www-form-urlencoded

이제 변경 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

분명히 파일 데이터는 전송되지 않았고 기본 이름 만 전송되었습니다. 따라서 파일에는 사용할 수 없습니다.

텍스트 필드에 관해서는, 우리는 같은 것을 보통의 인쇄 가능한 문자를 참조 ab같은 인쇄 할 수없는 것들 동안 1 바이트에 보내졌다 0xCF하고 0x89위로했다 3 바이트 각 : %CF%89!

비교

파일 업로드는 종종 인쇄 할 수없는 많은 문자 (예 : 이미지)를 포함하지만 텍스트 형식은 거의 없습니다.

예제에서 우리는 다음을 보았습니다.

  • multipart/form-data: 메시지에 몇 바이트의 경계 오버 헤드를 추가하고 계산하는 데 시간이 걸리지 만 각 바이트를 1 바이트로 보냅니다.

  • application/x-www-form-urlencoded: 필드 당 단일 바이트 경계 ( &)를 갖지만 인쇄 할 수없는 모든 문자에 대해 3 배선형 오버 헤드 계수를 추가합니다 .

따라서로 파일을 보낼 수 있어도 application/x-www-form-urlencoded비효율적이므로 원하지 않습니다.

그러나 텍스트 필드에있는 인쇄 가능한 문자의 경우 중요하지 않으며 오버 헤드가 적으므로 그냥 사용합니다.


3
Khanna111는 @ %CF긴 3 바이트이다 %, C그리고 F그 사람이 읽을 수있는 만드는 :-) 이야기.
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

6
OS X에서 nc모두 수락하지 않습니다 -l-p동시에 인수를. 그러나 이것은 나를 위해 작동합니다 while true; do printf '' | nc -l 8000; done.
PhilipS

4
언급되지 않은 작지만 중요한 점은에 지정된 경계 Content-Type가 두 개의 하이픈 ( --)이 적다는 것입니다. 즉, 실제로 메시지 본문에서 경계를 사용할 때는 접두사를 접두어로 사용해야합니다 --. 또한 마지막 경계에는 접미사가 붙어야 --하지만 알아 채기 쉽습니다. 참조 stackoverflow.com/questions/3508252/...
버나드

1
내가 알 수있는 한, DASHES AT ALL을 경계에 두는 요점은 눈으로 요청의 구문을 확인하는 것을 불가능하게하는 것입니다. 경계 토큰에 사용하지 마십시오.
Dewi Morgan

1
@DewiMorgan 당신은 완전히 옳습니다. 게시물을 편집하고 경계 문자열에서 대시를 제거했습니다.
최대

91

enctype='multipart/form-dataPOST를 통해 파일을 보낼 수있는 인코딩 유형입니다 . 간단히 말해서이 인코딩이 없으면 파일을 POST를 통해 보낼 수 없습니다 .

사용자가 양식을 통해 파일을 업로드 할 수있게하려면이 enctype 을 사용해야합니다 .


파일이 이진 파일이 아닌 경우이 파일없이 작업 할 수 있습니까?
Yugal Jindle

내가 이해 한 바에 따르면, multipart/form-data이진이 아닌 파일을 보내는 데 사용할 수는 있지만 비효율적입니다. application/x-www-form-urlencoded이진이 아닌 데이터를 보내는 올바른 방법을 사용 하는 것이지만 이진이 아닌 파일에 대한 경험이 많은 사람이 나를 수정해야 할 수도 있습니다.
매트 애즈 베리

11
multipart/form-data파일 전송 에 사용하는 주요 이점 은 프런트 엔드 및 백엔드에서 자동으로 작동한다는 것입니다. 특별한 취급이 필요하지 않습니다. 텍스트 만 포함하더라도 모든 파일은 이진 파일입니다. application/x-www-form-urlencoded첨부 파일없이 양식을 POST하는 표준 방법입니다. multipart/form-data첨부 파일이있는 양식을 POST하는 표준 방법입니다. ( 서버와 클라이언트 사이의 통신에 일반적으로 사용되는 application/jsonand와 같은 수많은 다른 인코딩도 있습니다 application/json-patch+json.)
Daniel Luna

6
이미지를 base64로 인코딩하여 일반 문자열 데이터로 보낼 수 있습니다.
제임스

3
위의 @Prospero의 의견 외에도 :를 사용하지 않고 POST를 통해 파일을 보낼 수 있습니다 multipart/form-data. 당신이 할 수없는 일은 JavaScript없이 일반적인 HTML 양식 제출을 사용하는 것입니다. 사용할 양식을 설정하는 multipart/form-data것은 JavaScript를 사용하지 않고 파일을 POST 할 수 있도록 HTML이 제공 하는 유일한 메커니즘입니다 . 나는 이것이 대답에서 충분히 명확하지 않다고 느끼고 순진한 독자는 파일을 보낼 수 없다는 것이 HTTPmultipart/form-data 의 한계 라고 생각할 수도 있습니다 . 그렇지 않습니다.
Mark Amery

81

양식을 제출할 때 HTTP 프로토콜을 통해 TCP / IP 프로토콜 메시지 구조로 올바르게 엔벨로프 된 메시지를 네트워크에 보내도록 브라우저에 지시하십시오. HTML 페이지에는 <form>s 를 사용하여 서버로 데이터를 보내는 방법이 있습니다.

양식이 제출되면 HTTP 요청이 작성되어 서버로 전송됩니다. 메시지에는 양식의 필드 이름과 사용자가 입력 한 값이 포함됩니다. 이 전송은 POST또는 GET HTTP 메소드로 발생할 수 있습니다 .

  • POST 브라우저에 HTTP 메시지를 작성하고 모든 내용을 메시지 본문에 넣도록 지시합니다 (보다 안전하고 유연하게 작업을 수행하는 매우 유용한 방법).
  • GETquerystring에 양식 데이터를 제출합니다 . 데이터 표현과 길이에 대한 제약이 있습니다.

서버로 양식을 보내는 방법 설명

메소드를 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 헤더 필드 의 파일 이름을 해석 할 때 중요
합니다.

이는 개발자이고 서버가 사용자가 제출 한 양식을 처리하여 중요한 정보가 포함되어있을 경우에 중요합니다.


1
가장 최근에 편집 한 후 보안에 관한 내용은 무엇을하는지에 대한 질문과 관련이 없습니다 enctype. 나는 그것이 multipart/form-dataRFC 에서 온 것임을 알고 있지만 그럼에도 불구하고 데이터가 application/x-www-form-urlencoded또는 로 전송되는지 여부에 완전히 직교하는 양식을 제출하는 것에 대한 임의의 보안 고려 사항 multipart/form-data입니다.
Mark Amery

38

enctype='multipart/form-data'문자가 인코딩되지 않음을 의미합니다. 서버에 파일을 업로드 할 때이 유형이 사용되는 이유입니다.
따라서 multipart/form-data양식에 파일 내용과 같은 이진 데이터를 업로드해야하는 경우에 사용됩니다.


8

파일 내용을 양식을 사용하여 URL 매개 변수에 넣을 수 없으므로 method 속성을 POST로 설정하십시오.

enctype의 값을 multipart / form-data로 설정하십시오. 데이터는 여러 파일로 분할되므로 각 파일에 대해 하나씩 추가 될 수 있으며 양식 본문의 텍스트에 대해서는 하나씩 있습니다.


이는 POST양식을 통해 파일을 제출하기에 충분 multipart/form-data하고 모호한 방식으로 추가하는 것이 보너스 라는 것을 의미합니다 . 그렇지 않습니다. 대부분의 파일은 반드시을 사용해야합니다 multipart/form-data.
underscore_d

1
  • enctype ( ENC ode TYPE ) 속성은 양식 데이터를 서버에 제출할 때 양식 데이터를 인코딩하는 방법을 지정합니다.
  • multipart / form-data 는 파일 업로드가있는 양식 요소에 사용되는 enctype 속성의 값 중 하나입니다. 다중 부분 은 양식 데이터가 여러 부분 으로 나누어 서버로 전송되는 것을 의미 합니다.

5
enctype 이 암호화 유형을 의미하지 않는다고 생각 합니다. 이 수준에는 암호화가 없습니다. 내 추측은 인코딩 유형이거나 동봉 된 유형입니다. 그러나 반드시 암호화 유형이 아닙니다.
Yeo

1
최종 글 머리 기호 는 여기 <head><body>관련이 없으며 혼란 스럽습니다.
Mark Amery

0

일반적으로 이것은 파일로 데이터를 업로드 해야하는 POST 양식이있을 때입니다 ... 이것은 서버가 전송 된 데이터를 인코딩하는 방법을 알려줍니다.이 경우 전송 및 업로드 만하 기 때문에 인코딩되지 않습니다 이미지를 업로드 할 때와 같이 파일을 서버에


-3

enctype 속성은 양식 데이터를 서버에 제출할 때 양식 데이터를 인코딩하는 방법을 지정합니다.

enctype 속성은 method = "post"인 경우에만 사용할 수 있습니다.

인코딩 된 문자가 없습니다. 파일 업로드 제어가있는 양식을 사용하는 경우이 값이 필요합니다.

에서 W3 스쿨


2
이 인용문에는 언급조차 없습니다 multipart/form-data. 또한 불분명합니다. "문자가 인코딩되지 않음"이라는 문장의 의미는 무엇입니까? -1.
Mark Amery 14
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.