Tại sao ảnh dán lên PTT không tự hiện? Đào source code, hóa ra có 4 bộ quy tắc khác nhau
Dán link mà ảnh không hiện, đừng vội nghĩ do mình gõ sai
Ai từng đăng ảnh lên các hội nhóm Facebook hay diễn đàn kiểu cũ chắc cũng từng gặp cảnh: cùng một link, có chỗ hiện thumbnail ngay, có chỗ chỉ trơ trọi một dòng chữ xanh. PTT — diễn đàn BBS lâu đời của Đài Loan — còn khó chịu hơn: cùng một link, mở bằng app điện thoại thì tự nhảy thành ảnh thu nhỏ, nhưng mở bằng bản web trên máy tính thì chỉ còn lại một chuỗi URL trơ trọi.
Đây không phải do bạn dán sai định dạng. Đằng sau ba chữ "PTT" thực ra là ít nhất bốn phần mềm hoàn toàn khác nhau, mỗi cái dùng logic riêng để quyết định "link này có nên tự động biến thành ảnh hay không". Có bộ chỉ nhìn đuôi file, có bộ dựa vào danh sách domain được tin cậy (whitelist), có bộ đòi cả hai điều kiện cùng lúc. Kỳ lạ nhất là có bộ bỏ qua luôn việc kiểm tra đuôi file, cứ đánh cược rằng bạn dán link Imgur — phần này mình sẽ nói kỹ hơn ở dưới.
Điều khiến nhiều người bối rối nhất không phải là "dịch vụ nào tốt hơn", mà là cảm giác chia rẽ này — cùng một link mà mỗi nơi cho một kết quả khác nhau. Tháng 10 năm 2025, board (PTT gọi là 板, tức là khu vực thảo luận) ask của PTT có một luồng thảo luận hỏi "dịch vụ lưu ảnh nào hỗ trợ tự động hiện ảnh", 原PO (nguyên PO, thuật ngữ của PTT chỉ người đăng bài gốc) kể rằng term.ptt.cc trước đây chỉ cần rê chuột vào link Imgur là ảnh tự hiện lên, nhưng nửa năm trước bắt đầu không còn hoạt động nữa. Câu này chỉ ra một sự thật nhiều người không để ý: cùng một phần mềm, cùng một dịch vụ lưu ảnh, quy tắc vẫn thay đổi theo thời gian, và chẳng ai thông báo chính thức cả. Thay vì tin theo lời đồn, mình đã đào thẳng source code của mấy phần mềm chính để đọc, và mỗi ô trong bài này đều có nguồn dẫn chứng cụ thể.
Xem ảnh trên PTT thực ra có 5 con đường, không phải "PTT" là một thứ duy nhất
Trước tiên phải làm rõ bối cảnh, không thì đọc bảng bên dưới sẽ rối.
- Terminal BBS thuần văn bản (PCMan, Welly): chỉ nhận chữ, link ảnh mãi mãi chỉ là một chuỗi ký tự, không bao giờ tự biến thành ảnh.
- Bài viết trên bản web www.ptt.cc: khi tải trang bài viết, phía server sẽ tự chuyển link hợp lệ thành thẻ
<img>. - term.ptt.cc: giả lập terminal chạy trên web, rê chuột vào link sẽ bật popup xem trước ảnh, xử lý bằng JavaScript phía client.
- PttChrome: client telnet chạy trên trình duyệt có từ lâu đời, ảnh được nhúng thẳng vào màn hình bài viết.
- App điện thoại (Mo PTT, JPTT, PiTT, BePTT): tự chuyển link thành thumbnail hiển thị luôn, đây là phần mềm đóng mã nguồn nên chỉ có thể dựa vào phản hồi cộng đồng và mô tả chính thức để suy đoán.
Sự khác biệt giữa hai nhóm đầu và ba nhóm sau lớn hơn nhiều so với bạn tưởng.
Đào source code — 4 bộ quy tắc, không cái nào giống cái nào
Bài viết trên bản web www.ptt.cc: server tự quyết, ưu tiên đuôi file nhưng không nhận WebP
Frontend web của www.ptt.cc tên là pttweb, source code công khai trên GitHub tại repo ptt/pttweb. File chịu trách nhiệm chuyển link trong bài thành ảnh là richcontent/url_based_finder.go, bên trong có một danh sách quy tắc so khớp theo thứ tự:
var defaultUrlPatterns = []*UrlPattern{
newUrlPattern(`^https?://(?:www\.youtube\.com/watch\?(?:.+&)*v=|youtu\.be/)([\w\-]+)`, handleYoutube),
newUrlPattern(`^https?://i\.imgur\.com/([\w]+)\.((?i)png|jpeg|jpg|gif)$`, handleImgurSingle),
newUrlPattern(`^http://picmoe\.net/d\.php\?id=(\d+)`, handlePicmoe),
newUrlPattern(`\.(?i:png|jpeg|jpg|gif)$`, handleGenericImage),
}
Điểm mấu chốt nằm ở dòng cuối cùng. Ba dòng đầu là quy tắc riêng cho YouTube, Imgur và picmoe.net, còn dòng thứ tư mới là chìa khóa: bất kỳ link nào, chỉ cần kết thúc bằng .png, .jpeg, .jpg hoặc .gif (không phân biệt hoa thường), bất kể thuộc dịch vụ lưu ảnh nào, đều sẽ được bọc thành thẻ <img> và hiển thị trực tiếp. Nói cách khác, bài viết trên bản web www.ptt.cc thực chất chạy theo logic "nhận đuôi file, không quan tâm domain" — ngược hoàn toàn với term.ptt.cc.
Nhưng quy tắc này đòi hỏi link phải kết thúc đúng bằng đuôi file, không được có query string phía sau (regex dùng $ để khóa cứng phần đuôi). Nếu link trực tiếp của dịch vụ lưu ảnh có dạng xxx.jpg?token=abc123 kèm tham số, nó sẽ không khớp với quy tắc cuối cùng này. Ngoài ra, .webp hoàn toàn không có trong danh sách — nghĩa là dù bạn dán một link ảnh WebP hợp lệ 100%, bài viết trên bản web www.ptt.cc vẫn không tự mở rộng, chỉ để lại mỗi cái link. Đây là điểm mình chưa thấy bài viết nào khác về đăng ảnh PTT nói rõ.
term.ptt.cc: ưu tiên whitelist domain, đuôi file là cửa ải thứ hai
Source code của term.ptt.cc nằm trên GitHub tại ptt/ptt-term, đây là một terminal web kết nối BBS qua WebSocket. Module chịu trách nhiệm mở ảnh khi rê chuột là src/plugins/media_previewer/image_preview_util.js, bên trong có sẵn danh sách domain được tin cậy mặc định:
export const INITIAL_TRUSTED_IMAGE_DOMAINS = [
"imgur.com", "imgtok.com", "meee.com.tw", "duk.tw",
"upload.cc", "ibb.co", "imgbb.com", "postimg.cc",
"twimg.com", "gyazo.com",
];
Để ý xem, danh sách này không có urusai.cc, cũng không có vgy.me, càng không có lpic.cc. Nhưng trên board ask của PTT rõ ràng có người nói urusai.cc, vgy.me tự hiện ảnh rất mượt ở máy họ. Mâu thuẫn không? Thực ra không — trong code còn có một hàm parseTrustedDomains, tức là danh sách whitelist này có thể tự thêm domain trong phần cài đặt, giá trị mặc định chỉ là mười cái "dùng luôn không cần chỉnh" chứ không phải tất cả. Nói cách khác, 鄉民 (dân làng — cách người dùng PTT tự gọi nhau) đó nhiều khả năng đã tự thêm urusai.cc vào cấu hình cá nhân, chứ không phải term.ptt.cc mặc định hỗ trợ cho tất cả mọi người. Đây là chỗ rất dễ bị hiểu nhầm thành "quy tắc chung của cả hệ thống".
Logic xử lý chia làm hai lớp: Imgur có regex riêng, kể cả link không kèm đuôi file vẫn nhận ra được; link bắt đầu bằng pbs.twimg.com/media/ được cho qua luôn mà không kiểm tra đuôi file; còn lại các domain trong whitelist thì link bắt buộc phải kết thúc bằng .jpg, .jpeg, .png, .gif, .webp hoặc .bmp (có query string vẫn tính, điểm này khác với bản web www.ptt.cc). Nói cách khác, term.ptt.cc là cửa ải kép "domain VÀ đuôi file", cả hai điều kiện đều phải đạt.
PttChrome: chỉ nhìn domain, đuôi file cũng lười kiểm tra
PttChrome là sản phẩm ra đời sớm hơn, phiên bản kinh điển được duy trì bởi iamchucky/PttChrome. File chịu trách nhiệm xem trước ảnh trên màn hình là js/term_view.js, dùng đoạn jQuery selector sau để chọn link cần xử lý:
var aNodes = $(".main a[href^='http://ppt.cc/'], .main a[type='p'], " +
".main a[href^='http://imgur.com/'], .main a[href^='https://imgur.com/'], " +
".main a[href^='https://flic.kr/p/'], .main a[href^='https://www.flickr.com/photos/']")
.not("a[href^='http://imgur.com/a/'], a[href^='https://imgur.com/a/'], " +
"a[href^='http://imgur.com/gallery/'], a[href^='https://imgur.com/gallery/']");
Đến đây thì hơi kẹt. PttChrome hoàn toàn không kiểm tra đuôi file, chỉ nhận diện phần đầu link — whitelist chỉ có link rút gọn ppt.cc, imgur.com (loại trừ trang album và gallery), flic.kr, flickr.com/photos. urusai.cc, vgy.me, duk.tw, meee, ImgBB, Postimages, lpic.cc đều không có trong danh sách, dán link trực tiếp chuẩn đến mấy cũng không được PttChrome tự mở rộng, mãi mãi chỉ là một dòng link màu xanh. Thú vị hơn là cách nó xử lý link Imgur: trong code trực tiếp viết lại link thành i.imgur.com/ID.jpg, cứng luôn đuôi file là .jpg, bất kể ảnh gốc là PNG hay GIF. Đây là một lỗi nhỏ tồn tại từ hơn chục năm trước đến giờ, bình thường không ai nhận ra vì Imgur thường vẫn trả về đúng ảnh dù đuôi file yêu cầu không khớp.
App điện thoại (Mo PTT, JPTT, PiTT): mã nguồn đóng, chỉ có thể ghép bằng chứng cộng đồng
Nói thật, phần này mình không thể đưa ra câu trả lời ở mức source code. Mo PTT, JPTT, PiTT đều là app thương mại đóng mã nguồn, không tìm được repo code tương ứng trên GitHub. Bằng chứng chắc chắn nhất mình tìm được là hai luồng thảo luận gần thời điểm nhau trên board ask của PTT (đăng vào tháng 6 và tháng 10 năm 2025), trong đó 鄉民 báo lại kết quả thực tế: meee.com.tw phải tự tay thêm đuôi .jpg mới tự hiện ảnh được, định dạng i.urusai.cc/ID.png của urusai.cc dùng được, imgpoi.com bị nghi ngờ "căn bản không có tính năng tự hiện ảnh". Những mô tả này đều hướng về phía "app nhận đuôi file", khá giống logic của bản web www.ptt.cc, nhưng chưa ai đưa ra được source code hay tài liệu kỹ thuật chính thức của mấy app này để xác nhận có whitelist domain hay không. Ô này mình đánh dấu rõ là chưa xác minh, không giả vờ đã tự bóc tách code của chúng.
So sánh 4 bộ quy tắc cùng lúc
| Client | Cơ sở phán đoán | Yêu cầu đuôi file | WebP | Mức độ bằng chứng |
|---|---|---|---|---|
| Bài viết bản web www.ptt.cc | Chỉ nhận đuôi file, không quan tâm domain | Phải kết thúc bằng .jpg/.jpeg/.png/.gif, cấm kèm query string | Không hỗ trợ | Source code (ptt/pttweb) |
| term.ptt.cc | Whitelist domain + đuôi file, cả hai cửa ải | Trong whitelist phải kết thúc bằng .jpg/.jpeg/.png/.gif/.webp/.bmp, được kèm query string | Hỗ trợ | Source code (ptt/ptt-term) |
| PttChrome | Chỉ nhận domain, không kiểm tra đuôi file | Không kiểm tra (link Imgur bị ép đổi thành .jpg) | Không áp dụng | Source code (iamchucky/PttChrome) |
| App điện thoại (Mo PTT/JPTT/PiTT) | Nghi là nhận đuôi file | Nghi là .jpg/.png/.gif dùng được | Chưa xác minh | Báo cáo cộng đồng, chưa thấy source code |
Đọc xong bảng này chắc bạn cũng hiểu: không tồn tại một "quy tắc chung của PTT" nào cả. Cùng một link ảnh, bốn client có thể cho ra bốn kết quả khác nhau.
Bảng tương thích Dịch vụ lưu ảnh × Client: dán link nào ở đâu mới tự hiện ảnh
Bảng này mình đối chiếu từng bộ quy tắc ở trên với định dạng link trực tiếp của các dịch vụ lưu ảnh phổ biến. "✅" nghĩa là theo logic quy tắc sẽ tự mở rộng, "❌" là không, "⚠️" là tùy vào bạn có chỉnh cài đặt hoặc đuôi file thủ công hay không.
| Dịch vụ lưu ảnh (ví dụ link trực tiếp) | Bản web www.ptt.cc | term.ptt.cc (mặc định) | PttChrome | App (báo cáo cộng đồng) |
|---|---|---|---|---|
Imgur i.imgur.com/ID.jpg |
✅ | ✅ | ✅ (bị ép đổi thành .jpg) | ✅ |
meee meee.com.tw/ID.jpg |
✅ | ✅ | ❌ | ✅ (cần tự thêm đuôi file) |
| duk.tw | ✅ (nếu có đuôi file) | ✅ | ❌ | Chưa xác minh |
urusai.cc i.urusai.cc/ID.png |
✅ (nếu có đuôi file) | ⚠️ cần tự thêm vào whitelist | ❌ | ✅ (báo cáo cộng đồng) |
| vgy.me | ✅ (nếu có đuôi file) | ⚠️ cần tự thêm vào whitelist | ❌ | Chưa xác minh, cộng đồng nói "phiền nhất" |
ImgBB ibb.co/i.ibb.co |
✅ (nếu có đuôi file) | ✅ | ❌ | Chưa xác minh |
Postimages postimg.cc |
✅ (nếu có đuôi file) | ✅ | ❌ | Chưa xác minh |
lpic.cc lpic.cc/{code} |
❌ (không có đuôi file) | ❌ (không nằm trong whitelist, và không có đuôi file) | ❌ | ❌ (không có link trực tiếp để dán) |
Dòng cuối cùng phải nói rõ ràng luôn.
So một chút với Zalo và các hội nhóm Facebook: kiểu chia sẻ ảnh mà người Việt hay dùng
Nói tới đây chợt nhớ, thói quen chia sẻ ảnh của người Việt trên Zalo hay hội nhóm Facebook lại đi theo hướng hoàn toàn khác so với PTT. Zalo gần như không có khái niệm "link ảnh trực tiếp từ dịch vụ bên thứ ba tự hiện ra trong đoạn chat" — ảnh gửi qua Zalo là upload thẳng lên server của Zalo, muốn chia sẻ tiếp thì gửi lại file ảnh, không phải dán link. Hội nhóm Facebook cũng vậy, ảnh đăng trong bài viết là upload trực tiếp, Facebook gần như chặn hết việc hiển thị ảnh nhúng từ domain lạ ngoài hệ sinh thái của họ vì lý do bảo mật và chống spam.
Nhìn lại thì PTT vẫn giữ lại kiểu chia sẻ theo "link trực tiếp" từ thời BBS, đây là điểm khác biệt lớn nhất so với các nền tảng người Việt quen dùng hằng ngày. Nếu quen tay upload ảnh thẳng lên Zalo hay Facebook rồi chuyển qua dùng PTT, cảm giác lúng túng vì "sao dán link mà không hiện ảnh" là chuyện hoàn toàn bình thường — không phải bạn làm sai, chỉ là hai hệ sinh thái vận hành theo hai logic khác hẳn nhau.
lpic.cc hiện tại có dán lên PTT để tự hiện ảnh được không? Không, đây là giới hạn hiện tại
Trước khi viết bài này mình đã kiểm tra lại định dạng link chia sẻ của chính lpic.cc. Hiện tại sau khi upload xong, link nhận được có dạng https://lpic.cc/{mã ngắn} — đây là link trang xem tác phẩm, không phải kiểu link trực tiếp kết thúc bằng đuôi ảnh như i.imgur.com/xxx.jpg. Điều này có nghĩa dù là quy tắc đuôi file của bản web www.ptt.cc, hay whitelist domain của term.ptt.cc và PttChrome, đều không nhận được nó. Trang chia sẻ tự nó có hiện thumbnail thật, nhưng đó là khi mở trang mới thấy, không phải kiểu "dán link là tự mở rộng ngay".
Thành thật mà nói, đây không phải tin vui cho ai muốn tự động hiện ảnh trực tiếp trên PTT, mình không định tô vẽ thành chuyện khác. Nếu nhu cầu của bạn đúng là dán link để app tự chuyển thành thumbnail, mấy dịch vụ có dấu tick ở bảng trên (Imgur, meee, hoặc vài cái nằm trong whitelist mặc định của term.ptt.cc) sẽ phù hợp hơn. Ưu điểm của kiểu trang chia sẻ như lpic.cc nằm ở chỗ khác — các tính năng tương tác trên trang như bảo vệ bằng mật khẩu, đếm lượt xem, khu vực bình luận, phù hợp hơn với những trường hợp bạn muốn kiểm soát "ai được xem, xem xong có bị ghi lại hay không", ví dụ như ảnh chụp giao dịch hay nội dung riêng tư — bạn gửi link để người khác bấm vào xem, chứ không phải ném ra cho ai đi ngang cũng tự thấy thumbnail. Hai nhu cầu vốn khác nhau, ép dùng chung sẽ khó chịu.
Vậy nên chọn thế nào?
Nếu chỉ quan tâm "dán lên là tự hiện ảnh ngay", hãy xem bạn chủ yếu dùng client nào mà quyết định: dùng app điện thoại là chính thì chọn Imgur hoặc meee (nhớ thêm đuôi file); xem bài viết qua bản web là chính thì dịch vụ nào có link trực tiếp đuôi file chuẩn đều được, nhưng nhớ WebP hoàn toàn không được bản web www.ptt.cc chấp nhận; dùng term.ptt.cc thì trước tiên kiểm tra xem dịch vụ đó có nằm trong whitelist cài đặt của mình chưa, chưa có thì nhớ tự thêm vào.
Nếu muốn dùng chung được trên nhiều client, Imgur hiện vẫn là lựa chọn duy nhất được cả bốn bộ quy tắc chấp nhận — cái giá phải trả là nó đã chặn IP Đài Loan từ phía upload, chuyện này mình có nói kỹ hơn trong bài hướng dẫn đăng ảnh lên PTT. Thật sự không có dịch vụ nào giúp bạn khỏi lo về định dạng trong mọi tình huống, cái này mình đã trải qua rồi, cũng không cần nói tốt giùm cho bên nào.
Câu hỏi thường gặp
Câu 1: Tại sao cùng một link Imgur, hôm qua còn tự hiện ảnh được, hôm nay lại không?
Imgur đã chặn IP Đài Loan từ tháng 5 năm 2025, nếu bạn đang ở Đài Loan thì bản thân việc kết nối tới i.imgur.com có thể đã không được, chuyện này không liên quan gì đến quy tắc của client PTT. Ngoài ra PttChrome sẽ ép link Imgur đổi thành đuôi .jpg, nếu ảnh gốc là PNG có nền trong suốt thì chất lượng hoặc độ trong suốt có thể bị lỗi, nhưng điều này không ảnh hưởng đến việc "có mở được ảnh hay không", chỉ ảnh hưởng đến hiệu ứng hiển thị.
Câu 2: Danh sách domain tin cậy của term.ptt.cc có tự chỉnh được không?
Nhìn từ source code, hàm parseTrustedDomains hỗ trợ đọc danh sách tùy chỉnh, nghĩa là đây là cài đặt có thể điều chỉnh được, không phải quy tắc cứng không đổi được. Còn giao diện thao tác nằm ở đâu, có cần tải lại trang mới có hiệu lực hay không thì mình chưa thực hiện được đường dẫn thao tác cụ thể, phần này nên vào thẳng menu cài đặt của term.ptt.cc để tìm thử.
Câu 3: App điện thoại có xem whitelist domain hay không, sao không có câu trả lời chắc chắn?
Vì Mo PTT, JPTT, PiTT đều là phần mềm đóng mã nguồn, không tìm được source code công khai để đối chiếu từng dòng. Mô tả trong bài về ba app này hoàn toàn dựa vào báo cáo thực tế từ 鄉民 trên board ask của PTT, không phải kết luận mình tự bóc tách code mà ra, điều này mình đã đánh dấu rõ là chưa xác minh trong bài, không giả vờ đã tự kiểm chứng.
Câu 4: Tại sao bản web www.ptt.cc không hỗ trợ WebP, nhưng term.ptt.cc lại hỗ trợ?
Vì đây là hai bộ code hoàn toàn độc lập, một bên là pttweb viết bằng Go chạy phía server, một bên là ptt-term viết bằng JavaScript chạy phía client, người bảo trì khác nhau, thời điểm phát triển cũng khác nhau. WebP trở nên phổ biến là chuyện tương đối gần đây, quy tắc của pttweb rõ ràng chưa được cập nhật theo. Đây chính là điểm bài viết này muốn nhấn mạnh: PTT không phải một hệ thống thống nhất, mà là một hệ sinh thái ghép từ nhiều phần mềm độc lập với nhau.
Câu 5: Người Việt Nam có truy cập trực tiếp được term.ptt.cc hay www.ptt.cc không?
Được, PTT là dịch vụ BBS của Đài Loan, truy cập bản web và term.ptt.cc từ mạng Việt Nam thông thường không bị hạn chế đặc biệt gì, không giống một số dịch vụ lưu ảnh nước ngoài (như Imgur chặn IP Đài Loan) bị giới hạn theo khu vực. Nhưng tốc độ truy cập còn phụ thuộc vào chất lượng đường truyền quốc tế, giờ cao điểm có thể chậm hơn, đây là chuyện khác hoàn toàn so với quy tắc hiện ảnh nói trong bài.
Nguồn tham khảo
- [請問] 支援PTT自動開圖的圖床 — board ask của PTT
- Re: [請問] 支援PTT自動開圖的圖床 — board ask của PTT
- ptt/pttweb — source code PTT BBS Web Frontend,
richcontent/url_based_finder.go - ptt/ptt-term — source code term.ptt.cc,
src/plugins/media_previewer/image_preview_util.js - iamchucky/PttChrome — source code PttChrome,
js/term_view.js - Hướng dẫn đầy đủ cách đăng ảnh lên PTT 2026 — blog lpic.cc