RFC 2045: MIME Phần 1 — Định dạng Phần Thân Thông điệp Internet
Tại Sao Điều Này Tồn Tại
RFC 5322 (và tiền thân RFC 822) đã định nghĩa email là văn bản US-ASCII thuần túy có độ dài dòng tối đa 998 ký tự. Điều đó tốt vào năm 1982. Nó không tốt cho email hiện đại, cần phải chứa:
- Văn bản trong các bộ ký tự không phải ASCII (UTF-8, ISO-8859-*, v.v.)
- Nội dung HTML với kiểu nội tuyến và hình ảnh
- Tệp đính kèm (PDF, hình ảnh, kho lưu trữ)
- Nhiều phần nội dung (văn bản + HTML + tệp đính kèm trong một tin nhắn)
MIME (Multipurpose Internet Mail Extensions) là một bộ năm RFC mở rộng email để xử lý tất cả những điều này trong khi vẫn tương thích ngược với cơ sở hạ tầng chỉ hỗ trợ ASCII gốc. RFC 2045 là Phần 1: nó định nghĩa các trường tiêu đề và cơ chế mã hóa làm cho tất cả những điều khác có thể xảy ra.
Cách Hoạt Động
RFC 2045 giới thiệu ba trường tiêu đề quan trọng và hai lược đồ mã hóa.
Tiêu Đề MIME-Version
Mỗi tin nhắn MIME phải bao gồm:
MIME-Version: 1.0
Điều này báo hiệu cho các ứng dụng mail nhận được rằng tin nhắn sử dụng các quy ước MIME. Nếu không có tiêu đề này, tin nhắn được coi là văn bản US-ASCII thuần túy theo RFC 5322. Phiên bản đã được 1.0 kể từ năm 1996 và chưa bao giờ thay đổi.
Tiêu Đề Content-Type
Khai báo loại phương tiện và kiểu con của nội dung, cộng với các tham số tùy chọn:
Content-Type: type/subtype; parameter=value
Ví dụ:
; Email văn bản thuần túy trong UTF-8 Content-Type: text/plain; charset=utf-8 ; Email HTML Content-Type: text/html; charset=utf-8 ; Tệp đính kèm PDF Content-Type: application/pdf; name="invoice.pdf" ; Tin nhắn đa phần (văn bản + HTML + tệp đính kèm) Content-Type: multipart/mixed; boundary="----=_Part_123"
Nếu không có Content-Type, giá trị mặc định là text/plain; charset=us-ascii — duy trì tương thích ngược với các tin nhắn trước MIME.
Tiêu Đề Content-Transfer-Encoding
SMTP được thiết kế để chứa văn bản ASCII 7-bit với các dòng không dài hơn 998 ký tự. Dữ liệu nhị phân (hình ảnh, PDF) và văn bản 8-bit (UTF-8) phải được mã hóa để phù hợp với những hạn chế này. RFC 2045 định nghĩa năm mã hóa truyền tải:
| Mã Hóa | Trường Hợp Sử Dụng | Chi Phí Chung |
|---|---|---|
7bit |
Văn bản US-ASCII (mặc định). Không cần mã hóa. | Không |
8bit |
Văn bản 8-bit (ví dụ: UTF-8). Yêu cầu phần mở rộng SMTP 8BITMIME. | Không |
binary |
Dữ liệu nhị phân tùy ý. Yêu cầu phần mở rộng SMTP BINARYMIME. | Không |
quoted-printable |
Văn bản chủ yếu ASCII với một số ký tự không phải ASCII. | ~5-10% |
base64 |
Dữ liệu nhị phân (hình ảnh, tệp) hoặc văn bản có nhiều ký tự không phải ASCII. | ~33% |
Mã Hóa Quoted-Printable
Được thiết kế cho văn bản chủ yếu là ASCII với các ký tự không phải ASCII thỉnh thoảng. Mỗi byte không phải ASCII được mã hóa là =XX trong đó XX là giá trị hex. Các dòng dài hơn 76 ký tự được gói mềm bằng = ở cuối.
; Gốc: "René sent the café menu" Content-Transfer-Encoding: quoted-printable Ren=C3=A9 sent the caf=C3=A9 menu
=C3=A9 là mã hóa UTF-8 của é (U+00E9), với mỗi byte được mã hóa hex.
Mã Hóa Base64
Mã hóa dữ liệu nhị phân tùy ý thành các ký tự ASCII (A-Z, a-z, 0-9, +, /). Mỗi 3 byte đầu vào trở thành 4 ký tự ASCII. Các dòng được gói tại 76 ký tự.
Content-Type: image/png; name="logo.png" Content-Transfer-Encoding: base64 iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34 AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB zN+OGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBl
Chi Tiết Kỹ Thuật Chính
Tiêu Đề Content-Disposition
Mặc dù không phải là một phần của RFC 2045 (nó đến từ RFC 2183), Content-Disposition liên quan chặt chẽ và được sử dụng rộng rãi với MIME:
; Hiển thị nội tuyến (ví dụ: hình ảnh được nhúng) Content-Disposition: inline ; Cung cấp như một tệp đính kèm có thể tải xuống Content-Disposition: attachment; filename="report.pdf"
Một Tin Nhắn MIME Hoàn Chỉnh
Đặt tất cả lại với nhau — một tin nhắn có cả nội dung văn bản và HTML, cộng với một tệp đính kèm:
MIME-Version: 1.0 From: sender@example.com To: recipient@example.com Subject: Invoice attached Content-Type: multipart/mixed; boundary="----=_outer" ------=_outer Content-Type: multipart/alternative; boundary="----=_inner" ------=_inner Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Please find your invoice attached. ------=_inner Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable <p>Please find your invoice attached.</p> ------=_inner-- ------=_outer Content-Type: application/pdf; name="invoice.pdf" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="invoice.pdf" JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAv Q2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCg== ------=_outer--
Lưu ý cấu trúc: multipart/mixed chứa nội dung và tệp đính kèm. Bản thân nội dung là multipart/alternative với phiên bản văn bản và HTML. Xem RFC 2046 để biết toàn bộ chi tiết về các loại đa phần.
Tham Số Charset
Tham số charset trên các loại text/* khai báo mã hóa ký tự. Đối với email hiện đại, luôn sử dụng utf-8:
Content-Type: text/plain; charset=utf-8 Content-Type: text/html; charset=utf-8
Các bộ ký tự cũ như iso-8859-1, windows-1252, và shift_jis vẫn được gặp nhưng không nên được sử dụng trong các tin nhắn mới.
Những Sai Lầm Thường Gặp
-
Thiếu
MIME-Version: 1.0. Nếu không có tiêu đề này, một số ứng dụng mail bỏ qua Content-Type và coi nội dung là văn bản ASCII thuần túy. Email HTML của bạn sẽ hiển thị dưới dạng mã nguồn thô. -
Content-Transfer-Encoding sai cho dữ liệu nhị phân. Gửi tệp đính kèm nhị phân với mã hóa
7bitsẽ làm hỏng nó — các byte rỗng và ký tự bit cao bị xáo trộn. Luôn sử dụngbase64cho nội dung nhị phân. -
Thiếu hoặc sai tham số
charset. Bỏ qua charset mặc định làus-ascii. Nếu văn bản của bạn chứa các ký tự UTF-8, chúng sẽ hiển thị là rác. Luôn khai báocharset=utf-8. - Các dòng vượt quá 998 ký tự. RFC 5322 bắt buộc giới hạn độ dài dòng 998 ký tự. Base64 gói tại 76 ký tự. Quoted-printable sử dụng các ngắt dòng mềm. Văn bản 8bit thô cũng phải tuân theo giới hạn này, nếu không các máy chủ trung gian có thể cắt ngắn hoặc từ chối tin nhắn.
-
Sử dụng
8bitmà không kiểm tra hỗ trợ máy chủ. Mã hóa8bityêu cầu máy chủ nhận phải quảng cáo8BITMIMEtrong phản hồi EHLO của nó. Nếu nó không quảng cáo, hãy sử dụng quoted-printable hoặc base64 thay thế. - Chuỗi ranh giới xuất hiện trong nội dung nội dung. Ranh giới đa phần không được xuất hiện trong bất kỳ phần nội dung nào. Sử dụng một chuỗi ranh giới dài, ngẫu nhiên để tránh va chạm.
Tác Động Đến Khả Năng Gửi
- Cấu trúc MIME thích hợp là bắt buộc. MIME bị lỗi kích hoạt bộ lọc thư rác. MIME-Version bị thiếu, các ranh giới không chính xác, hoặc mã hóa sai đều là những dấu hiệu đỏ mà bộ lọc thư rác tìm kiếm.
-
Luôn gửi multipart/alternative. Bao gồm cả
text/plainvàtext/htmlphần. Các tin nhắn chỉ có HTML bị phạt bởi nhiều bộ lọc thư rác. Phần văn bản cũng đóng vai trò là dự phòng cho các ứng dụng văn bản thuần túy. - Sử dụng base64 cho tệp đính kèm, quoted-printable cho văn bản. Đây là sự kết hợp tương thích phổ quát. Nó hoạt động trên mọi máy chủ SMTP và ứng dụng mail.
- Giữ kích thước tệp đính kèm hợp lý. Mã hóa Base64 tăng 33% chi phí chung. Một tệp 7,5 MB trở thành email 10 MB. Nhiều máy chủ từ chối tin nhắn trên 25 MB. Một số trên 10 MB.
-
Charset chính xác ngăn chặn lỗi kết xuất. Khai báo
charset=utf-8và thực sự mã hóa trong UTF-8 đảm bảo email của bạn kết xuất chính xác trên toàn thế giới. Các khai báo charset không khớp gây ra mojibake (văn bản bị xáo trộn) và khiếu nại hỗ trợ.