RFC 2231: Mở rộng Giá trị Tham số MIME
Tại Sao Điều Này Tồn Tại
Các tham số MIME xuất hiện trong các tiêu đề như Content-Type và Content-Disposition. Trường hợp sử dụng phổ biến nhất là tham số filename cho các tệp đính kèm:
Content-Disposition: attachment; filename="report.pdf"
Điều này hoạt động tốt cho các tên tệp ASCII. Nhưng nếu là tệp có tên 報告書.pdf (tiếng Nhật có nghĩa là "báo cáo") hoặc tên tệp có 200 ký tự thì sao? Đặc tả MIME gốc (RFC 2045) không có cơ chế nào cho điều này. RFC 2231 giải quyết ba vấn đề:
- Bộ ký tự: mã hóa ký tự không phải ASCII trong giá trị tham số
- Thẻ ngôn ngữ: chú thích giá trị tham số bằng mã định danh ngôn ngữ
- Tiếp tục: chia các giá trị tham số dài trên nhiều dòng
Cách Hoạt Động
Mã Hóa Bộ Ký Tự và Ngôn Ngữ
Để bao gồm các ký tự không phải ASCII, thêm dấu hoa thị vào tên tham số và sử dụng định dạng charset'language'encoded-value:
Content-Disposition: attachment; filename*=UTF-8''%E5%A0%B1%E5%91%8A%E6%9B%B8.pdf ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^ charset lang percent-encoded value (empty = no language tag)
Giá trị %E5%A0%B1%E5%91%8A%E6%9B%B8 là các byte UTF-8 cho "報告書" được mã hóa phần trăm. Thẻ ngôn ngữ giữa các dấu ngoặc kép đơn là tùy chọn (thường bỏ trống).
Tiếp Tục Cho Các Giá Trị Dài
Khi giá trị tham số quá dài cho một dòng tiêu đề duy nhất, hãy chia nó bằng cách tiếp tục được đánh số:
Content-Type: application/pdf; filename*0="very-long-document-name-that-exceeds-the"; filename*1="-reasonable-line-length-limit-for-headers.pdf"
Các phần được tập hợp lại theo thứ tự số: *0, *1, *2, v.v.
Kết Hợp: Tiếp Tục Với Bộ Ký Tự
Đối với các giá trị không phải ASCII dài, kết hợp cả hai tính năng. Chỉ phân đoạn đầu tiên bao gồm bộ ký tự và ngôn ngữ; các phân đoạn tiếp theo chỉ là các giá trị được mã hóa:
Content-Disposition: attachment; filename*0*=UTF-8''%E3%81%93%E3%82%8C%E3%81%AF%E9%95%B7; filename*1*=%E3%81%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB; filename*2*=%E5%90%8C%E3%83%A1.pdf ^^^^ number + asterisk = encoded continuation
Chi Tiết Kỹ Thuật Chính
Cú Pháp Tên Tham Số
| Biểu Mẫu | Ý Nghĩa | Ví Dụ |
|---|---|---|
filename |
Giá trị ASCII thuần túy | filename="report.pdf" |
filename* |
Giá trị được mã hóa (charset'lang'value) | filename*=UTF-8''%E5%A0%B1.pdf |
filename*0 |
Phần tiếp tục 0, ASCII thuần túy | filename*0="very-long-" |
filename*0* |
Phần tiếp tục 0, được mã hóa | filename*0*=UTF-8''%E5%A0%B1 |
Quy Tắc Mã Hóa
- Sử dụng mã hóa phần trăm (giống như mã hóa URL) cho các octet không phải ASCII
- Các ký tự ASCII an toàn trong các token MIME (chữ cái, chữ số, dấu gạch ngang, dấu chấm) không cần mã hóa
- Bộ ký tự gần như luôn là
UTF-8trong thực hành hiện đại - Thẻ ngôn ngữ tuân theo BCP 47 (ví dụ:
en,ja,zh-CN) nhưng thường bị bỏ qua
Tương Tác Với RFC 2047
RFC 2047 cung cấp các encoded-words (=?UTF-8?B?...?=) cho văn bản không phải ASCII trong tiêu đề. Tuy nhiên, RFC 2047 rõ ràng nêu rằng các encoded-words KHÔNG được xuất hiện bên trong các chuỗi được trích dẫn hoặc giá trị tham số. RFC 2231 là cơ chế chính xác cho các tham số MIME. Mặc dù có quy tắc này, nhiều ứng dụng thư sử dụng mã hóa RFC 2047 trong các tham số filename anyway, vì vậy các trình phân tích cú pháp mạnh mẽ phải xử lý cả hai.
Những Sai Lầm Phổ Biến
-
Sử dụng mã hóa RFC 2047 trong giá trị tham số. Viết
filename="=?UTF-8?B?...?="về mặt kỹ thuật là không hợp lệ, nhưng rất phổ biến. Để có khả năng tương thích tối đa, gửi cả hai: mộtfilenamethuần túy có fallback ASCII và mộtfilename*với giá trị được mã hóa RFC 2231. -
Quên dấu hoa thị kép cho các tiếp tục được mã hóa.
filename*1là một tiếp tục văn bản thuần túy.filename*1*là một tiếp tục được mã hóa. Thiếu dấu hoa thị ở cuối có nghĩa là giá trị sẽ được coi là văn bản theo nghĩa đen, không được giải mã. - Thứ tự tiếp tục sai. Các phần phải được đánh số liên tiếp bắt đầu từ 0. Khoảng trống trong đánh số (0, 1, 3) hoặc bắt đầu từ 1 thay vì 0 sẽ gây ra lỗi phân tích cú pháp trong các triển khai nghiêm ngặt.
- Sử dụng bộ ký tự khác ngoài UTF-8. Mặc dù RFC 2231 cho phép bất kỳ bộ ký tự IANA nào, thực hành hiện đại là UTF-8 độc quyền. Sử dụng ISO-8859-1 hoặc Windows-1252 làm giảm khả năng tương thích với các người nhận quốc tế.
-
Không cung cấp fallback ASCII. Một số ứng dụng thư cũ hơn không hỗ trợ RFC 2231. Luôn bao gồm một tham số
filenamethuần túy có xấp xỉ ASCII cùng với tham sốfilename*.
Tác Động Khả Năng Gửi
- Hiển thị tên tệp đính kèm. Mã hóa không chính xác gây ra tên tệp đính kèm xuất hiện dưới dạng văn bản bị lỗi hoặc dấu hỏi trong ứng dụng thư của người nhận. Điều này gây nhầm lẫn và không chuyên nghiệp, mặc dù nó không ảnh hưởng trực tiếp đến việc tin nhắn được gửi.
- Kích hoạt bộ lọc thư rác. Các tham số MIME hình thành không đúng có thể kích hoạt các bộ lọc thư rác. Một số bộ lọc đánh dấu các tin nhắn có bất thường trong mã hóa là đáng ngờ, vì các chiến dịch phần mềm độc hại đôi khi sử dụng các tiêu đề hình thành không đúng để khai thác các lỗ hổng của trình phân tích cú pháp.
-
Khả năng tương thích trên các ứng dụng khách. Trạng thái thực tế của hỗ trợ RFC 2231 khác nhau. Gmail, Apple Mail và Thunderbird xử lý nó tốt. Một số ứng dụng doanh nghiệp cũ hơn thì không. Cách tiếp cận an toàn nhất là luôn bao gồm cả
filename(ASCII) vàfilename*(RFC 2231) tham số. -
Các tham số Content-Type cũng vậy. Mặc dù
filenamelà trường hợp sử dụng rõ ràng nhất, RFC 2231 cũng áp dụng cho các tham sốContent-Typenhưnamevàcharset, và bất kỳ tham số tiêu đề MIME nào khác.