Tra cứu MIME type: từ đuôi file ra Content-Type và ngược lại
Công cụ tra hai chiều giữa đuôi tệp và kiểu MIME trên bảng dữ liệu 293 đuôi thuộc mười nhóm. Mỗi mục ghi rõ kiểu đã đăng ký với IANA hay chưa, có nên bật nén khi phục vụ qua web hay không, và dựng sẵn dòng header Content-Type đầy đủ kèm charset để bạn chép thẳng vào cấu hình máy chủ.
Tính năng nổi bật
- Tra xuôi: nhập đuôi tệp như docx hoặc .webp, nhận ngay kiểu MIME nên đặt cho máy chủ
- Tra ngược: nhập một kiểu MIME, nhận danh sách mọi đuôi tệp trong bảng dùng chung kiểu đó
- Bảng dữ liệu 293 đuôi tệp chia mười nhóm: văn bản, mã nguồn, dữ liệu, ảnh, âm thanh, video, font, tài liệu văn phòng, nén và ứng dụng
- Mỗi mục có nhãn cho biết kiểu đã được đăng ký chính thức trong sổ media type của IANA hay chỉ là quy ước thực tế
- Khuyến nghị nén riêng cho từng đuôi, phân biệt tệp nên bật gzip với tệp đã nén sẵn không nên nén lại
- Dòng header Content-Type dựng sẵn kèm charset đúng chỗ cần, có nút chép cho từng dòng
- Ô tìm kiếm lọc bảng theo đuôi, theo kiểu MIME hoặc theo mô tả, kèm mười nút lọc nhóm
- Ghi chú riêng cho các trường hợp dễ nhầm như .ts, .svgz, .json, .woff2 và các đuôi Office thực chất là ZIP
Vì sao đặt sai Content-Type lại gây lỗi khó tìm
Trình duyệt không quyết định cách xử lý một tệp dựa trên đuôi trong địa chỉ, nó nghe theo header Content-Type mà máy chủ trả về. Đặt sai header thì hậu quả không hiện ra dưới dạng lỗi rõ ràng mà dưới dạng những triệu chứng khó lần: tệp .mjs trả về application/octet-stream khiến trình duyệt từ chối nạp module và cả ứng dụng trắng trang, tệp .wasm không có kiểu application/wasm khiến hàm biên dịch theo luồng thất bại và phải chạy đường vòng chậm hơn, tệp .svg trả về text/plain thì hiện ra một mớ mã XML thay vì hình vẽ, font .woff2 sai kiểu thì chữ nhảy sang font dự phòng mà bảng điều khiển không báo lỗi nào. Ở chiều bảo mật, đặt Content-Type quá rộng cho tệp người dùng tải lên là con đường kinh điển để chèn mã: một tệp có phần thân là HTML nhưng được trả về với kiểu text/html sẽ chạy script ngay trong tên miền của bạn. Bảng tra này gom sẵn kiểu đúng cho từng đuôi, kèm cả những chỗ mà quy ước thực tế khác với sổ đăng ký chính thức, để bạn không phải đoán.
Lợi ích khi sử dụng
- Biết ngay kiểu đúng thay vì chép nhầm từ một câu trả lời cũ trên diễn đàn
- Phân biệt được kiểu đã đăng ký IANA với kiểu chỉ là quy ước, quan trọng khi viết tài liệu kỹ thuật hoặc kiểm thử tương thích
- Tránh bật nén cho tệp đã nén sẵn, thứ chỉ tốn CPU mà không giảm được byte nào
- Có sẵn dòng header đúng chuẩn để dán vào cấu hình máy chủ, không phải tự ghép charset
- Duyệt theo nhóm giúp rà soát cả một mảng cấu hình, chẳng hạn kiểm tra hết các đuôi font hoặc video một lượt
Cách tra cứu MIME type
- 1Ở thẻ Đuôi file ra MIME type, gõ đuôi tệp cần tra, có dấu chấm hay không đều được, dán cả tên tệp cũng được vì công cụ tự lấy phần sau dấu chấm cuối cùng.
- 2Đọc thẻ kết quả: dòng đầu là kiểu MIME, ba nhãn bên dưới cho biết nhóm, trạng thái đăng ký IANA và khuyến nghị nén.
- 3Bấm nút chép ở khung màu xanh để lấy nguyên dòng Content-Type đã có sẵn charset, dán thẳng vào cấu hình Nginx, Apache hoặc mã nguồn phía máy chủ.
- 4Chuyển sang thẻ MIME type ra đuôi file khi bạn cầm một header lạ và muốn biết nó tương ứng với những đuôi nào, nhập một phần kiểu cũng được.
- 5Kéo xuống bảng đầy đủ, dùng ô tìm kiếm hoặc mười nút lọc nhóm để duyệt theo chủ đề, ví dụ xem hết nhóm font hoặc nhóm nén.
Cấu trúc một kiểu MIME và ba tham số hay gặp
Một kiểu MIME luôn gồm hai phần ngăn bởi dấu gạch chéo: kiểu chính và kiểu con, ví dụ trong image/webp thì image là kiểu chính còn webp là kiểu con. Kiểu chính lấy từ một danh sách đóng gồm text, image, audio, video, application, font, model, message, multipart và example, trong đó application là chỗ chứa mọi thứ không rơi vào các nhóm còn lại nên nó phình to nhất. Kiểu con thì mở, và tiền tố của nó nói lên nguồn gốc: tiền tố vnd. nghĩa là kiểu do một nhà cung cấp cụ thể đăng ký, như application/vnd.rar hay application/vnd.android.package-archive; tiền tố prs. dành cho cá nhân; tiền tố x- là dấu vết của thời kỳ chưa có quy trình đăng ký, như application/x-7z-compressed, và tuy đã bị khuyến nghị ngừng dùng từ lâu nhưng nhiều kiểu x- vẫn phổ biến hơn kiểu chính thức nên bảng này giữ chúng. Phần đuôi cũng có quy ước: hậu tố +xml báo rằng bên trong là XML như application/atom+xml, hậu tố +json báo bên trong là JSON như application/ld+json, hậu tố +zip báo tệp thực chất là kho ZIP như application/epub+zip. Sau kiểu con có thể có tham số, gặp nhiều nhất là charset, rồi tới boundary trong multipart và profile trong một số kiểu JSON có lược đồ.
Khi nào phải ghi charset và khi nào ghi thừa gây hại
Charset chỉ có nghĩa với những kiểu mà nội dung là chuỗi ký tự cần giải mã, tức gần như toàn bộ nhóm text và một số kiểu application chứa văn bản. Với chúng, thiếu charset là lỗi thật sự: trình duyệt sẽ đoán bảng mã, và với tiếng Việt thì đoán sai dẫn tới chữ hiện ra thành ký tự lạ. Header đúng cho một trang web là text/html; charset=utf-8, và tuy thẻ meta trong HTML cũng khai báo được nhưng header có mức ưu tiên cao hơn nên khai báo mâu thuẫn thì header thắng. Ở chiều ngược lại, ghi charset cho kiểu nhị phân là ghi thừa và có thể gây hiểu nhầm khi kiểm thử: image/png; charset=utf-8 không sai cú pháp nhưng vô nghĩa vì PNG không phải chuỗi ký tự. Có một ngoại lệ đáng nhớ là application/json: đặc tả của JSON quy định nội dung luôn phải mã hóa bằng UTF-8, nên tham số charset đã bị loại khỏi định nghĩa kiểu này, ghi thêm charset=utf-8 vào không làm hỏng gì nhưng là thừa và một số công cụ kiểm tra sẽ cảnh báo. Bảng ở trên đã xử lý sẵn chuyện này: dòng header dựng ra chỉ kèm charset ở đúng những mục cần.
Nén khi phục vụ qua web: chỗ nào có lợi, chỗ nào chỉ tốn CPU
Quy tắc gốc rất đơn giản: nén chỉ có lợi khi dữ liệu còn dư thừa để nén. Văn bản, mã nguồn, JSON, XML, SVG, bảng CSV đều là chuỗi ký tự lặp lại nhiều nên gzip thường giảm được bảy tới chín phần mười dung lượng, Brotli còn tốt hơn với các tệp mã nguồn. Ngược lại, mọi định dạng đã nén sẵn ở bên trong thì nén thêm gần như vô ích: JPEG, PNG, GIF, WebP, AVIF, MP3, MP4, ZIP, gzip, 7z, RAR, PDF và đặc biệt là WOFF2 vốn đã dùng Brotli ngay trong định dạng. Nén lại nhóm này chỉ tiêu tốn CPU máy chủ, tăng thời gian tới byte đầu tiên, và trong vài trường hợp còn làm tệp phình ra vài byte. Vài trường hợp nằm giữa mà bảng này ghi rõ để bạn khỏi phải đoán: BMP, TIFF, WAV và TAR đều là định dạng gần như không nén nên gzip giảm rất mạnh, đáng bật; TTF và OTF cũng nén tốt trong khi WOFF và WOFF2 thì không; các tệp Office đuôi x như docx, xlsx, pptx thực chất là kho ZIP nên hãy để yên. Riêng .svgz là trường hợp đặc biệt, nó đã là SVG nén gzip sẵn nên máy chủ phải trả về image/svg+xml kèm header Content-Encoding: gzip, thiếu header thứ hai thì trình duyệt nhận về một đống byte không đọc được.
Những đuôi tệp dễ gây nhầm nhất trong bảng
Nổi tiếng nhất là .ts. Trong sổ đăng ký IANA, .ts thuộc về video/mp2t, tức luồng truyền tải MPEG dùng trong truyền hình số và trong phát trực tuyến HLS. Nhưng cùng đuôi đó lại là mã nguồn TypeScript, thứ chưa bao giờ được đăng ký kiểu riêng. Hậu quả thực tế là một số máy chủ cấu hình sẵn sẽ trả tệp TypeScript với kiểu video, và nếu bạn phục vụ mã nguồn cho trình duyệt thì trình duyệt từ chối. Nhóm thứ hai là các đuôi thực chất là ZIP: docx, xlsx, pptx, odt, ods, epub, jar, war, apk, xpi, whl, nupkg và usdz đều là kho ZIP có cấu trúc thư mục quy ước bên trong, nên chúng chia chung chữ ký nhị phân và chỉ phân biệt được bằng tên các tệp nằm trong kho. Nhóm thứ ba là các đuôi có hai kiểu cùng lưu hành: .ico có kiểu chuẩn image/vnd.microsoft.icon nhưng image/x-icon vẫn xuất hiện khắp nơi; .wav có kiểu đăng ký audio/vnd.wave nhưng audio/wav phổ biến hơn nhiều; .avi có video/vnd.avi đăng ký nhưng video/x-msvideo mới là thứ các máy chủ thật sự trả về. Nhóm cuối là .db, một đuôi mơ hồ tới mức nhiều phần mềm khác nhau dùng cho các định dạng hoàn toàn không liên quan, nên chỉ nhìn đuôi thì không thể kết luận được gì.
Đuôi tệp là lời khai, chữ ký nhị phân mới là bằng chứng
Trang này và trang nhận diện chữ ký tại /vi/tools/file-signature-identifier trả lời hai câu hỏi khác hẳn nhau, và biết ranh giới giữa chúng sẽ tiết kiệm cho bạn rất nhiều thời gian. Trang bạn đang xem tra theo đuôi tệp mà người dùng khai, đúng như cách máy chủ web tra bảng ánh xạ để đặt header Content-Type, nên nó không mở tệp ra và cũng không cần tệp: bạn chỉ gõ một chuỗi ký tự. Trang kia đọc mấy trăm byte đầu của tệp thật rồi đối chiếu với bảng chữ ký nhị phân của hơn tám mươi định dạng, nên nó nói cho bạn biết ruột tệp là gì bất kể tên gọi ra sao. Cặp đôi này hữu ích nhất khi hai kết quả lệch nhau: một tệp tên bao-gia.pdf mà chữ ký thật là ZIP thì nhiều khả năng là tệp Office đổi đuôi, còn nếu chữ ký là MZ thì đó là tệp thực thi Windows giả dạng tài liệu, một mẫu tấn công cũ nhưng vẫn hiệu quả với người nhận thư. Trong quy trình xử lý tệp tải lên, cách làm đúng là dùng cả hai: lấy đuôi để biết người dùng định gửi gì, đọc chữ ký để biết họ thật sự gửi gì, chỉ chấp nhận khi hai thứ khớp nhau, rồi mới đặt header theo bảng ánh xạ chứ đừng dùng lại chuỗi Content-Type do trình duyệt gửi lên.
Ranh giới với các công cụ tra cứu và xử lý tệp khác trên site
Site có vài trang trông cùng dạng bảng tra nhưng phục vụ tầng khác nhau của một yêu cầu HTTP, nên chọn đúng trang sẽ nhanh hơn nhiều. Trang này nói về header Content-Type, tức phần mô tả nội dung. Nếu bạn cần tra ý nghĩa của con số phản hồi như 301, 404 hay 502 thì dùng /vi/tools/http-status-reference. Nếu bạn đang phân vân giữa GET, POST, PUT, PATCH và cần biết phương thức nào an toàn, phương thức nào lặp lại được thì dùng /vi/tools/http-method-reference. Nếu bạn cần biết dịch vụ nào chiếm cổng nào khi mở tường lửa thì dùng /vi/tools/port-reference. Ở mảng xử lý tệp, /vi/tools/file-hash-checker tính hash toàn bộ tệp để kiểm tra tính toàn vẹn, tức trả lời câu hỏi tệp này có bị sửa một byte nào không, hoàn toàn khác việc nhận dạng định dạng. Nếu bạn muốn xem thông tin chụp ảnh nằm trong ảnh thì dùng /vi/tools/image-metadata-viewer, còn nếu cần nhúng ảnh thành chuỗi dán thẳng vào CSS hay HTML thì dùng /vi/tools/base64-image, nơi chuỗi kết quả cũng cần đúng kiểu MIME mà bạn tra được ở trang này.
Câu hỏi thường gặp (FAQ)
MIME type của file .docx là gì?
Là application/vnd.openxmlformats-officedocument.wordprocessingml.document, một chuỗi dài nhưng phải viết đủ. Đây là kiểu đã đăng ký với IANA. Vì tệp docx thực chất là kho ZIP nên đừng bật nén thêm khi phục vụ qua web, bạn sẽ không tiết kiệm được byte nào.
Vì sao file .mjs của tôi không nạp được trên máy chủ thật?
Gần như chắc chắn máy chủ chưa biết đuôi .mjs nên trả về application/octet-stream. Trình duyệt chỉ nạp module khi kiểu MIME nằm trong nhóm JavaScript hợp lệ. Hãy khai báo .mjs thành text/javascript trong bảng ánh xạ của Nginx hoặc Apache rồi nạp lại cấu hình.
Nên dùng text/javascript hay application/javascript?
Dùng text/javascript. Từ khi RFC 9239 ra đời, application/javascript và các biến thể khác đã bị đánh dấu lỗi thời, text/javascript trở thành kiểu duy nhất được khuyến nghị. Cả hai đều chạy được trên trình duyệt, nhưng khi viết cấu hình mới thì nên theo kiểu được khuyến nghị.
File SVG nên đặt Content-Type thế nào cho đúng?
Đặt image/svg+xml kèm charset=utf-8 vì SVG là XML chứa chữ. Đây cũng là ảnh duy nhất nên bật nén, thường giảm được bảy tới tám phần mười dung lượng. Nếu tệp có đuôi .svgz thì giữ nguyên kiểu image/svg+xml nhưng phải thêm header Content-Encoding: gzip.
Kiểu chuẩn IANA nghĩa là gì và có bắt buộc dùng không?
Nghĩa là kiểu đó đã được đăng ký chính thức trong sổ media type do IANA quản lý, có tài liệu mô tả và tên không bị tranh chấp. Không bắt buộc, trình duyệt vẫn hiểu nhiều kiểu chưa đăng ký như video/webm hay video/x-matroska. Nhưng khi viết tài liệu kỹ thuật hoặc làm việc với hệ thống kiểm định thì nên ưu tiên kiểu đã đăng ký.
Vì sao AVIF và WebP lại không nên bật nén?
Vì bản thân hai định dạng này đã nén ảnh rất mạnh ở bên trong. Chạy gzip lên dữ liệu đã nén thì tỷ lệ giảm gần bằng không, đôi khi tệp còn phình thêm vài byte do phần mào đầu của gzip. Bạn chỉ tốn CPU máy chủ và tăng thời gian chờ byte đầu tiên mà không được lợi gì.
Đuôi .ts sao lại ra kiểu video?
Vì trong sổ đăng ký IANA, .ts thuộc về video/mp2t, luồng truyền tải MPEG dùng cho truyền hình số và phát trực tuyến HLS. Mã nguồn TypeScript dùng chung đuôi này nhưng chưa từng được đăng ký kiểu riêng. Khi phục vụ mã TypeScript cho trình duyệt, hãy tự khai báo text/javascript sau khi biên dịch.
Máy chủ nên trả kiểu gì cho một đuôi file lạ không có trong bảng?
Trả application/octet-stream. Đó là kiểu quy ước cho dữ liệu nhị phân không xác định, trình duyệt sẽ tải xuống thay vì tự mở. Tuyệt đối không đoán bừa một kiểu gần đúng, vì đoán sang text/html là mở đường cho mã trong tệp chạy ngay trong tên miền của bạn.
Vì sao application/json không cần ghi charset?
Vì đặc tả của JSON quy định nội dung luôn được mã hóa bằng UTF-8, nên tham số charset đã bị loại khỏi định nghĩa kiểu này. Ghi thêm charset=utf-8 không làm hỏng gì và trình duyệt bỏ qua, nhưng đó là ghi thừa và một số công cụ kiểm tra cấu hình sẽ báo cảnh báo.
Vì sao nhiều đuôi file khác nhau lại trả về cùng một MIME type?
Vì kiểu MIME mô tả nội dung chứ không mô tả tên. Chẳng hạn .jpg, .jpeg, .jpe và .jfif đều là ảnh JPEG nên đều dùng image/jpeg; .yaml và .yml là cùng một định dạng chỉ khác cách viết đuôi. Thẻ tra ngược trong công cụ liệt kê hết các đuôi dùng chung một kiểu.
Trình duyệt có tự đoán kiểu file khi máy chủ đặt sai không?
Có, cơ chế đó gọi là đánh hơi nội dung và nó từng là nguồn gốc của nhiều lỗ hổng, vì một tệp tải lên trông như ảnh có thể bị đoán thành HTML rồi chạy script. Vì vậy nên gửi kèm header X-Content-Type-Options: nosniff để buộc trình duyệt tôn trọng đúng kiểu bạn khai báo.
Tôi nhận file tải lên từ người dùng, có nên tin Content-Type trình duyệt gửi lên không?
Không nên. Trường đó do phía gửi tự khai và sửa được bằng vài dòng lệnh. Hãy tự xác định kiểu ở phía máy chủ, tốt nhất là đọc mấy byte đầu để đối chiếu chữ ký nhị phân, rồi mới dùng bảng ánh xạ trong trang này để đặt header khi phục vụ lại tệp đó.
Công cụ này có mở file của tôi ra để kiểm tra không?
Không, nó chỉ tra theo chuỗi ký tự bạn gõ vào và không nhận tệp. Nếu bạn muốn biết ruột tệp thật sự là định dạng gì, hãy dùng công cụ nhận diện chữ ký tại /vi/tools/file-signature-identifier, trang đó đọc mấy trăm byte đầu và cảnh báo khi đuôi không khớp nội dung.
Từ khóa liên quan
- tra cứu mime type
- mime type là gì
- mime type của file docx
- content type header là gì
- mime type webp
- mime type svg
- mime type file mjs
- danh sách mime type đầy đủ
- mime type avif
- đặt content type cho nginx
- add_type nginx mime types
- charset utf-8 trong content type
- nên nén gzip những loại file nào
- application/octet-stream là gì
- x-content-type-options nosniff
- mime type chuẩn iana
- mime type file zip và docx
- phân biệt đuôi file và mime type
- mime type video mp4 và webm
- mime type font woff2
