파일을 내부적으로 어떻게 보냅니 까?
형식은 호출 multipart/form-data
에서 요청과 같은 : 무엇에 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ω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 유형은 브라우저에 의해 어떻게 결정됩니까?
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
분명히 파일 데이터는 전송되지 않았고 기본 이름 만 전송되었습니다. 따라서 파일에는 사용할 수 없습니다.
텍스트 필드에 관해서는, 우리는 같은 것을 보통의 인쇄 가능한 문자를 참조 a
와 b
같은 인쇄 할 수없는 것들 동안 1 바이트에 보내졌다 0xCF
하고 0x89
위로했다 3 바이트 각 : %CF%89
!
비교
파일 업로드는 종종 인쇄 할 수없는 많은 문자 (예 : 이미지)를 포함하지만 텍스트 형식은 거의 없습니다.
예제에서 우리는 다음을 보았습니다.
따라서로 파일을 보낼 수 있어도 application/x-www-form-urlencoded
비효율적이므로 원하지 않습니다.
그러나 텍스트 필드에있는 인쇄 가능한 문자의 경우 중요하지 않으며 오버 헤드가 적으므로 그냥 사용하십시오.