ĐỌC LẠI PARA ĐẦU TIÊN TẠI ĐÂY!
Tôi biết rằng đây là 3 năm quá muộn, nhưng câu trả lời (được chấp nhận) của Matt không đầy đủ và cuối cùng sẽ khiến bạn gặp rắc rối. Chìa khóa ở đây là, nếu bạn chọn sử dụng multipart/form-data
, ranh giới không được xuất hiện trong dữ liệu tệp mà cuối cùng máy chủ nhận được.
Đây không phải là một vấn đề cho application/x-www-form-urlencoded
, bởi vì không có ranh giới. x-www-form-urlencoded
cũng có thể luôn luôn xử lý dữ liệu nhị phân, bằng cách đơn giản là biến một byte tùy ý thành ba 7BIT
byte. Không hiệu quả, nhưng nó hoạt động (và lưu ý rằng nhận xét về việc không thể gửi tên tệp cũng như dữ liệu nhị phân là không chính xác; bạn chỉ cần gửi nó dưới dạng cặp khóa / giá trị khác).
Vấn đề với multipart/form-data
là không phải có dấu phân cách ranh giới trong dữ liệu tệp (xem RFC 2388 ; phần 5.2 cũng bao gồm một lý do khá khập khiễng vì không có loại MIME tổng hợp phù hợp để tránh vấn đề này).
Vì vậy, ngay từ cái nhìn đầu tiên, multipart/form-data
không có giá trị gì trong bất kỳ tập tin tải lên, nhị phân hay cách khác. Nếu bạn không chọn đúng ranh giới của mình, thì cuối cùng bạn sẽ gặp vấn đề, cho dù bạn đang gửi văn bản thuần túy hoặc nhị phân thô - máy chủ sẽ tìm thấy một ranh giới ở sai vị trí và tệp của bạn sẽ bị cắt bớt hoặc POST sẽ thất bại.
Điều quan trọng là chọn mã hóa và ranh giới sao cho các ký tự ranh giới được chọn của bạn không thể xuất hiện trong đầu ra được mã hóa. Một giải pháp đơn giản là sử dụng base64
( không sử dụng nhị phân thô). Trong base64 3 byte tùy ý được mã hóa thành bốn ký tự 7 bit, trong đó bộ ký tự đầu ra là [A-Za-z0-9+/=]
(tức là chữ và số, '+', '/' hoặc '='). =
là trường hợp đặc biệt và chỉ có thể xuất hiện ở cuối đầu ra được mã hóa, dưới dạng đơn =
hoặc kép ==
. Bây giờ, chọn ranh giới của bạn dưới dạng chuỗi ASCII 7 bit không thể xuất hiện ở base64
đầu ra. Nhiều lựa chọn bạn thấy trên mạng thất bại trong bài kiểm tra này - MDN tạo thành tài liệu, ví dụ: sử dụng "blob" làm ranh giới khi gửi dữ liệu nhị phân - không tốt. Tuy nhiên, một cái gì đó như "! Blob!" sẽ không bao giờ xuất hiện trong base64
đầu ra.