Helpex - Trao đổi & giúp đỡ Đăng nhập
1149

Điều gì có enctype='multipart/form-data'nghĩa trong một hình thức HTML và khi nào chúng ta nên sử dụng nó?

1149 hữu ích 1 bình luận 856k xem chia sẻ
1297

Khi bạn thực hiện một yêu cầu POST, bạn phải mã hóa dữ liệu tạo thành phần thân của yêu cầu theo một cách nào đó.

Các hình thức HTML cung cấp ba phương pháp mã hóa.

  • application/x-www-form-urlencoded (mặc định)
  • multipart/form-data
  • text/plain

Công việc đã được thực hiện trên thêm application/json, nhưng điều đó đã bị bỏ rơi.

(Có thể mã hóa khác với các yêu cầu HTTP được tạo bằng các phương tiện khác ngoài việc gửi biểu mẫu HTML.)

Các chi tiết cụ thể của các định dạng không quan trọng đối với hầu hết các nhà phát triển. Những điểm quan trọng là:

  • Không bao giờ sử dụng text/plain.

Khi bạn đang viết mã phía máy khách:

  • sử dụng multipart/form-datakhi biểu mẫu của bạn bao gồm bất kỳ <input type="file">yếu tố nào
  • nếu không bạn có thể sử dụng multipart/form-datahay application/x-www-form-urlencodednhưng application/x-www-form-urlencodedsẽ hiệu quả hơn

Khi bạn đang viết mã phía máy chủ:

  • Sử dụng thư viện xử lý biểu mẫu được viết sẵn

Hầu hết (chẳng hạn như Perl's CGI->paramhoặc người được tiếp xúc bởi siêu lớp của PHP $_POST) sẽ quan tâm đến sự khác biệt dành cho bạn. Đừng cố gắng phân tích cú pháp đầu vào thô mà máy chủ nhận được.

Đôi khi bạn sẽ tìm thấy một thư viện không thể xử lý cả hai định dạng. Thư viện phổ biến nhất của Node.js để xử lý dữ liệu biểu mẫu là trình phân tích cú pháp cơ thể không thể xử lý các yêu cầu nhiều phần (nhưng có tài liệu đề xuất một số lựa chọn thay thế có thể).


Nếu bạn đang viết (hoặc gỡ lỗi) một thư viện để phân tích cú pháp hoặc tạo dữ liệu thô, thì bạn cần bắt đầu lo lắng về định dạng. Bạn cũng có thể muốn biết về nó vì lợi ích.

application/x-www-form-urlencoded ít nhiều giống với chuỗi truy vấn ở cuối URL.

multipart/form-dataphức tạp hơn đáng kể nhưng nó cho phép bao gồm toàn bộ tập tin trong dữ liệu. Một ví dụ về kết quả có thể được tìm thấy trong đặc tả HTML 4 .

text/plainđược giới thiệu bởi HTML 5 và chỉ hữu ích để gỡ lỗi - từ thông số kỹ thuật : Chúng không thể hiểu được bằng máy tính - và tôi cho rằng những cái khác kết hợp với các công cụ (như tab Net trong công cụ phát triển của hầu hết các trình duyệt) thì tốt hơn cho điều đó).

1297 hữu ích 5 bình luận chia sẻ
362

khi nào chúng ta nên sử dụng nó

Câu trả lời của Quentin là đúng: sử dụng multipart/form-datanếu biểu mẫu có chứa tệp tải lên và application/x-www-form-urlencodednếu không, đó là mặc định nếu bạn bỏ qua enctype.

Tôi sẽ:

  • thêm một số tài liệu tham khảo HTML5
  • giải thích lý do tại sao anh ta đúng với một ví dụ gửi mẫu

Tài liệu tham khảo HTML5

ba khả năng cho enctype:

Cách tạo các ví dụ

Khi bạn thấy một ví dụ về mỗi phương thức, nó sẽ trở nên rõ ràng về cách chúng hoạt động và khi nào bạn nên sử dụng từng phương thức.

Bạn có thể tạo các ví dụ bằng cách sử dụng:

Lưu biểu mẫu vào một .htmltệp tối thiểu :

<!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>

Chúng tôi thiết lập các giá trị văn bản mặc định a&#x03C9;b, có nghĩa là aωbbởi vì ωU+03C9, đó là các byte 61 CF 89 62trong UTF-8.

Tạo tập tin để tải lên:

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

Chạy máy chủ echo nhỏ của chúng tôi:

while true; do printf '' | nc -l 8000 localhost; done

Mở HTML trên trình duyệt của bạn, chọn các tệp và nhấp vào gửi và kiểm tra thiết bị đầu cuối.

nc in yêu cầu nhận được.

Đã thử nghiệm trên: Ubuntu 14.04.3, ncBSD 1.105, Firefox 40.

nhiều dữ liệu / biểu mẫu

Firefox đã gửi:

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--

Đối với tệp nhị phân và trường văn bản, các byte 61 CF 89 62( aωbtrong UTF-8) được gửi theo nghĩa đen. Bạn có thể xác minh rằng với nc -l localhost 8000 | hd, nói rằng các byte:

61 CF 89 62

đã được gửi ( 61== 'a' và 62== 'b').

Vì vậy, rõ ràng rằng:

  • Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266đặt loại nội dung thành multipart/form-datavà nói rằng các trường được phân tách bằng boundarychuỗi đã cho .

  • mỗi trường có một số tiêu đề phụ trước dữ liệu của nó : Content-Disposition: form-data;, trường name, the filename, theo sau là dữ liệu.

    Máy chủ đọc dữ liệu cho đến chuỗi ranh giới tiếp theo. Trình duyệt phải chọn một ranh giới sẽ không xuất hiện trong bất kỳ trường nào, vì vậy đây là lý do tại sao ranh giới có thể khác nhau giữa các yêu cầu.

    Bởi vì chúng tôi có ranh giới duy nhất, không cần mã hóa dữ liệu: dữ liệu nhị phân được gửi như hiện có.

    TODO: kích thước ranh giới tối ưu ( log(N)tôi đặt cược) và tên / thời gian chạy của thuật toán tìm thấy nó là gì? Đã hỏi tại: https://cs.stackexchange.com/questions/39487/find-the-shortest- resultence-that-is-not-a-sub-resultence-of-a-set-of- result

  • Content-Type được tự động xác định bởi trình duyệt.

    Làm thế nào nó được xác định chính xác đã được hỏi tại: Làm thế nào loại mime của một tệp tải lên được xác định bởi trình duyệt?

ứng dụng / x-www-form-urlencoding

Bây giờ thay đổi enctypethành application/x-www-form-urlencoded, tải lại trình duyệt và gửi lại.

Firefox đã gửi:

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

Rõ ràng dữ liệu tệp không được gửi, chỉ có các tên cơ sở. Vì vậy, điều này không thể được sử dụng cho các tập tin.

Đối với trường văn bản, chúng tôi thấy rằng các ký tự có thể in thông thường như abđược gửi trong một byte, trong khi các ký tự không in được như thế 0xCF0x89chiếm 3 byte mỗi ký tự : %CF%89!

So sánh

Tải lên tệp thường chứa nhiều ký tự không in được (ví dụ hình ảnh), trong khi các hình thức văn bản hầu như không bao giờ thực hiện.

Từ các ví dụ chúng ta đã thấy rằng:

  • multipart/form-data: thêm một vài byte chi phí biên cho thông báo và phải dành thời gian để tính toán nó, nhưng sẽ gửi mỗi byte trong một byte.

  • application/x-www-form-urlencoded: có một ranh giới byte đơn trên mỗi trường ( &), nhưng thêm hệ số chi phí tuyến tính3x cho mỗi ký tự không in được.

Do đó, ngay cả khi chúng tôi có thể gửi tệp cùng application/x-www-form-urlencoded, chúng tôi sẽ không muốn, vì nó rất kém hiệu quả.

Nhưng đối với các ký tự có thể in được tìm thấy trong các trường văn bản, nó không quan trọng và tạo ra ít chi phí hơn, vì vậy chúng tôi chỉ sử dụng nó.

362 hữu ích 5 bình luận chia sẻ
80

enctype='multipart/form-datalà một loại mã hóa cho phép các tệp được gửi qua POST . Rất đơn giản, không có mã hóa này, các tệp có thể được gửi qua POST .

Nếu bạn muốn cho phép người dùng tải lên một tập tin thông qua một hình thức, bạn phải sử dụng này enctype .

80 hữu ích 5 bình luận chia sẻ
71

Khi gửi biểu mẫu, bạn yêu cầu trình duyệt của bạn gửi, thông qua giao thức HTTP, một thông báo trên mạng, được bao bọc đúng cách trong cấu trúc thông báo giao thức TCP / IP. Một trang HTML có một cách để gửi dữ liệu đến máy chủ: bằng cách sử dụng <form>s.

Khi một biểu mẫu được gửi, Yêu cầu HTTP nếu được tạo và gửi đến máy chủ, thông báo sẽ chứa tên trường trong biểu mẫu và các giá trị được điền bởi người dùng. Việc truyền này có thể xảy ra với POSThoặc GET các phương thức HTTP .

  • POST yêu cầu trình duyệt của bạn xây dựng một thông điệp HTTP và đặt tất cả nội dung vào phần thân của tin nhắn (một cách làm rất hữu ích, an toàn hơn và cũng linh hoạt hơn).
  • GETsẽ gửi dữ liệu biểu mẫu trong chuỗi truy vấn . Nó có một số hạn chế về biểu diễn dữ liệu và độ dài.

Nêu cách gửi biểu mẫu của bạn đến máy chủ

Thuộc tính chỉ enctypecó ý nghĩa khi sử dụng POSTphương pháp. Khi được chỉ định, nó sẽ hướng dẫn trình duyệt gửi biểu mẫu bằng cách mã hóa nội dung của nó theo một cách cụ thể. Từ MDN - Mẫu mã :

Khi giá trị của thuộc tính phương thức là post, enctype là loại nội dung MIME được sử dụng để gửi biểu mẫu đến máy chủ.

  • application/x-www-form-urlencoded: Đây là mặc định. Khi biểu mẫu được gửi, tất cả tên và giá trị được thu thập và Mã hóa URL được thực hiện trên chuỗi cuối cùng.
  • multipart/form-data: Ký tự KHÔNG được mã hóa. Điều này rất quan trọng khi biểu mẫu có kiểm soát tải lên tệp. Bạn muốn gửi tệp nhị phân và điều này đảm bảo rằng dòng bit không bị thay đổi.
  • text/plain: Spaces được chuyển đổi, nhưng không thực hiện thêm mã hóa.

Bảo vệ

Khi gửi biểu mẫu, một số lo ngại về bảo mật có thể phát sinh như được nêu trong RFC 7578 Phần 7: Dữ liệu biểu mẫu nhiều phần - Cân nhắc bảo mật :

Tất cả các phần mềm xử lý biểu mẫu phải xử lý dữ liệu biểu mẫu do người dùng cung cấp
có độ nhạy, vì phần mềm này thường chứa
thông tin nhận dạng cá nhân hoặc bí mật . Việc sử dụng rộng rãi các tính năng "tự động điền" trong các trình duyệt web; chúng có thể được sử dụng để lừa người dùng
vô tình gửi thông tin bí mật khi hoàn thành
các nhiệm vụ vô hại. dữ liệu đa dữ liệu / biểu mẫu không cung cấp bất kỳ tính năng nào
để kiểm tra tính toàn vẹn, đảm bảo tính bảo mật, tránh
sự nhầm lẫn của người dùng hoặc các tính năng bảo mật khác; những mối quan tâm đó phải được
giải quyết bằng các ứng dụng điền biểu mẫu và giải thích dữ liệu biểu mẫu.

Các ứng dụng nhận biểu mẫu và xử lý chúng phải cẩn thận không cung cấp dữ liệu trở lại trang web xử lý biểu mẫu yêu cầu không được gửi.

Điều quan trọng khi diễn giải tên tệp của trường
tiêu đề Nội dung để không vô tình ghi đè lên các tệp trong
không gian tệp của người nhận.

Điều này liên quan đến bạn nếu bạn là nhà phát triển và máy chủ của bạn sẽ xử lý các biểu mẫu được gửi bởi người dùng có thể chứa thông tin nhạy cảm.

71 hữu ích 1 bình luận chia sẻ
30

enctype='multipart/form-data'có nghĩa là không có ký tự sẽ được mã hóa. đó là lý do tại sao loại này được sử dụng trong khi tải tệp lên máy chủ.
Vì vậy, multipart/form-datađược sử dụng khi một biểu mẫu yêu cầu dữ liệu nhị phân, như nội dung của tệp, được tải lên

30 hữu ích 0 bình luận chia sẻ
8

Đặt thuộc tính phương thức thành POST vì nội dung tệp không thể được đặt trong tham số URL bằng biểu mẫu.

Đặt giá trị của mã hóa thành nhiều dữ liệu / biểu mẫu dữ liệu vì dữ liệu sẽ được chia thành nhiều phần, một phần cho mỗi tệp cộng với một cho văn bản của phần thân biểu mẫu có thể được gửi cùng với chúng.

8 hữu ích 1 bình luận chia sẻ
0

Thông thường đây là khi bạn có một biểu mẫu POST cần lấy tệp tải lên dưới dạng dữ liệu ... điều này sẽ cho máy chủ biết cách mã hóa dữ liệu được truyền, trong trường hợp đó nó sẽ không được mã hóa bởi vì nó sẽ chỉ truyền và tải lên các tệp đến máy chủ, ví dụ như khi tải lên hình ảnh hoặc pdf

0 hữu ích 0 bình luận chia sẻ
0
  • thuộc tính enctype ( ENC ode TYPE ) chỉ định cách mã hóa dữ liệu biểu mẫu khi gửi nó đến máy chủ.
  • Multipart / form-data là một trong những giá trị của thuộc tính enctype, được sử dụng trong phần tử biểu mẫu có tải lên tệp. đa phần có nghĩa là dữ liệu biểu mẫu chia thành nhiều phần và gửi đến máy chủ.
0 hữu ích 2 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ html http-headers multipartform-data , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading