Вернуться в блог
Сообщество

Почему картинка на PTT не открывается сама: в исходном коде нашлось 4 разных правила

Опубликовано13 min read
Поделиться

Одна ссылка — четыре разных результата, и дело не в вас

Если вы никогда не пользовались PTT, вот суть в двух словах: это старейшая и крупнейшая текстовая BBS (bulletin board system) на Тайване, до сих пор работающая через telnet-подобный терминал, с миллионами активных аккаунтов. Любой, кто там что-то постит, рано или поздно сталкивается с одной и той же загадкой — вставляешь ссылку на картинку, а она то превращается в миниатюру, то так и остаётся синей подчёркнутой строкой.

Честно говоря, у большинства первая мысль — что где-то напутали с форматом ссылки. Нет. Удивляет вовсе не то, «какой хостинг лучше», а то, что одна и та же ссылка автоматически разворачивается в миниатюру в мобильном приложении и превращается в голый URL на десктопной веб-версии — при этом пользователь ничего не менял.

Это не совпадение и не ваша ошибка. Под названием «PTT» на самом деле скрывается минимум четыре совершенно разных программы, и каждая по-своему решает, превращать ли ссылку в изображение. Одни смотрят только на расширение файла, другие — на белый список доменов, третьи требуют выполнения обоих условий сразу. Есть даже вариант ещё интереснее — проверка расширения вообще пропускается, программа просто исходит из того, что вы вставили ссылку на Imgur. Об этом расскажу дальше.

В октябре 2025 года на форумной секции ask на PTT (это раздел вопросов от сообщества) как раз обсуждали, какие хостинги поддерживают автоматическое открытие картинок. Автор поста — на жаргоне PTT его называют 原po — написал, что раньше при наведении курсора на ссылку Imgur в term.ptt.cc всплывало превью, но полгода назад это перестало работать. Вот факт, который многие упускают: один и тот же клиент, один и тот же хостинг, а правила со временем меняются, и никто об этом официально не объявляет. Вместо того чтобы полагаться на слухи, я сам залез в исходный код основных клиентов, и под каждой строкой этого разбора есть проверяемый источник.

В Telegram-чатах у нас похожая история

Если кажется, что это чисто тайваньская проблема, вспомните любой Telegram-чат или паблик во ВКонтакте — ссылка на картинку то разворачивается превью, то остаётся просто текстом. Telegram и VK опираются на Open Graph-метатеги страницы, а клиенты PTT читают напрямую паттерн URL — технология другая, но суть проблемы та же: у каждой платформы своё внутреннее правило, единого стандарта нет ни у кого.

Просмотр картинок на PTT: 5 разных путей, а не один «PTT»

Прежде чем идти дальше, стоит разложить сценарии по полочкам, иначе таблица ниже будет непонятной.

  • Текстовый терминал BBS (PCMan, Welly): читает только текст, ссылка на картинку навсегда остаётся строкой, сама в изображение не превращается.
  • Статья в веб-версии www.ptt.cc: при чтении поста сервер сам конвертирует подходящие под правило URL прямо в тег <img>.
  • term.ptt.cc: веб-эмулятор терминала, при наведении курсора на ссылку фронтенд на JavaScript показывает превью.
  • PttChrome: давний браузерный telnet-клиент, картинка встраивается прямо в текст поста.
  • Мобильные приложения (Mo PTT, JPTT, PiTT, BePTT): превращают ссылку сразу в миниатюру, но это закрытый исходный код, приходится опираться только на отчёты сообщества и официальные описания.

Разница между первыми двумя вариантами и последними тремя куда больше, чем кажется на первый взгляд.

Я залез в исходный код — 4 правила, ни одно не похоже на другое

Статья в веб-версии www.ptt.cc: решение на стороне сервера, приоритет расширению, но без WebP

Фронтенд www.ptt.cc называется pttweb, исходный код открыт на GitHub в репозитории ptt/pttweb. За превращение ссылок в посте в картинки отвечает файл richcontent/url_based_finder.go, где список правил проверяется по порядку:

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),
}

Главное — последняя строка. Первые три правила заточены под YouTube, Imgur и picmoe.net, а вот четвёртое — ключевое: любой URL, заканчивающийся на .png, .jpeg, .jpg или .gif (регистр не важен), независимо от хостинга, оборачивается в тег <img> и показывается напрямую. Получается, что статья в веб-версии www.ptt.cc работает по логике «смотрим на расширение, а не на домен» — прямая противоположность term.ptt.cc.

Но у этого правила есть условие: URL должен заканчиваться именно расширением, без query-параметров после него (регулярка жёстко закрепляет конец строки символом $). Если прямая ссылка хостинга выглядит как xxx.jpg?token=abc123, последнее правило не сработает. И .webp в списке нет вообще — то есть даже настоящая прямая ссылка на WebP-файл в статье веб-версии www.ptt.cc сама не развернётся, останется просто URL. В других разборах формата картинок на PTT этот момент обычно нигде чётко не объясняется.

term.ptt.cc: сначала белый список доменов, расширение — вторым фильтром

Исходный код term.ptt.cc лежит на GitHub в ptt/ptt-term — это веб-терминал, подключающийся к BBS через WebSocket. За превью при наведении курсора отвечает модуль src/plugins/media_previewer/image_preview_util.js, где прямо в коде прописан список доверенных доменов по умолчанию:

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",
];

Заметили? В этом списке нет ни urusai.cc, ни vgy.me, ни тем более lpic.cc. При этом на форумной секции ask кто-то писал, что urusai.cc и vgy.me у него открываются автоматически без проблем. Противоречия тут нет — в коде есть функция parseTrustedDomains, а значит, этот белый список можно расширять через настройки; десять доменов по умолчанию — это лишь набор «из коробки», а не полный перечень. Иными словами, тот пользователь, скорее всего, сам добавил urusai.cc в личные настройки, а не term.ptt.cc поддерживает его для всех по умолчанию. Это как раз то место, где легко принять личную настройку за общее правило сайта.

Логика проверки состоит из двух уровней: у Imgur есть отдельное регулярное выражение, распознающее ссылку даже без расширения; ссылки, начинающиеся с pbs.twimg.com/media/, пропускаются без проверки расширения вообще; для всех остальных доменов из белого списка URL обязан заканчиваться на .jpg, .jpeg, .png, .gif, .webp или .bmp (query-параметры допустимы, в отличие от веб-версии www.ptt.cc). То есть term.ptt.cc требует одновременно «домен И расширение» — двойной барьер.

PttChrome: смотрит только на домен, расширение вообще не проверяет

PttChrome — программа постарше, классическую версию поддерживают в репозитории iamchucky/PttChrome. За превью картинок отвечает файл js/term_view.js, а для выбора нужных ссылок используется вот такой jQuery-селектор:

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/']");

Тут ситуация несколько неловкая. PttChrome вообще не проверяет расширение, смотрит только на начало URL — в белом списке лишь короткие ссылки ppt.cc, imgur.com (кроме альбомов и страниц gallery), flic.kr и flickr.com/photos. Ни urusai.cc, ни vgy.me, ни duk.tw, ни meee, ни ImgBB, ни Postimages, ни lpic.cc там нет — сколько ни вставляй идеально оформленную прямую ссылку, PttChrome её никогда не развернёт, так и останется синей строкой. А самое любопытное — как обрабатываются ссылки Imgur: код прямо переписывает URL в i.imgur.com/ID.jpg, расширение .jpg зашито намертво, независимо от того, PNG это на самом деле или GIF. Это мелкий баг, доставшийся программе больше десяти лет назад, который обычно никто не замечает, потому что Imgur всё равно чаще всего возвращает нужную картинку даже при неверном расширении в запросе.

Мобильные приложения (Mo PTT, JPTT, PiTT): закрытый код, только свидетельства сообщества

Честно скажу: здесь я не могу дать ответ на уровне исходного кода. Mo PTT, JPTT, PiTT — все три коммерческие закрытые приложения, соответствующего репозитория на GitHub не существует. Самое надёжное, что удалось найти, — это две близкие по времени темы на форумной секции ask (одна за июнь 2025 года, другая за октябрь 2025 года), где пользователи делились наблюдениями: если вручную добавить .jpg к ссылке meee.com.tw, картинка открывается сама; формат i.urusai.cc/ID.png у urusai.cc работает; а про imgpoi.com сомневались, что там вообще есть автоматическое открытие. Все эти признаки указывают на логику «смотрим на расширение», которая ближе к веб-версии www.ptt.cc, но ни у кого нет исходного кода или официальной технической документации этих приложений, чтобы подтвердить, есть ли там ещё и белый список доменов. Этот пункт я честно помечаю как непроверенный, не притворяясь, что сам разбирал их код.

Все 4 правила рядом для сравнения

Клиент На чём основано решение Требование к расширению WebP Уровень доказательности
Статья веб-версии www.ptt.cc Только расширение, домен не важен Должно заканчиваться на .jpg/.jpeg/.png/.gif, query-строка запрещена Не поддерживается Исходный код (ptt/pttweb)
term.ptt.cc Белый список доменов + расширение, двойной барьер На доменах из списка нужно .jpg/.jpeg/.png/.gif/.webp/.bmp, query-строка допустима Поддерживается Исходный код (ptt/ptt-term)
PttChrome Только домен, расширение не проверяется Не проверяется (ссылки Imgur принудительно переписываются в .jpg) Не применимо Исходный код (iamchucky/PttChrome)
Мобильные приложения (Mo PTT/JPTT/PiTT) Предположительно по расширению Предположительно работают .jpg/.png/.gif Непроверено Отчёты сообщества, исходный код недоступен

Из этой таблицы ясно одно: никакого «единого правила PTT» не существует. Одна и та же ссылка на изображение может дать четыре разных результата на четырёх разных клиентах.

Таблица совместимости хостингов и клиентов

Эту таблицу я собрал, применив каждое из правил выше к форматам прямых ссылок популярных хостингов. «✅» означает, что по логике правила картинка должна открыться сама, «❌» — что не откроется, «⚠️» — что зависит от личных настроек или расширения ссылки.

Хостинг (пример прямой ссылки) Веб-статья www.ptt.cc term.ptt.cc (по умолчанию) PttChrome Приложение (по отчётам сообщества)
Imgur i.imgur.com/ID.jpg ✅ ✅ ✅ (принудительно .jpg) ✅
meee meee.com.tw/ID.jpg ✅ ✅ ❌ ✅ (нужно вручную добавить расширение)
duk.tw ✅ (если есть расширение) ✅ ❌ Непроверено
urusai.cc i.urusai.cc/ID.png ✅ (если есть расширение) ⚠️ нужно вручную добавить в белый список ❌ ✅ (по отчётам сообщества)
vgy.me ✅ (если есть расширение) ⚠️ нужно вручную добавить в белый список ❌ Непроверено, сообщество называет «самым проблемным»
ImgBB ibb.co / i.ibb.co ✅ (если есть расширение) ✅ ❌ Непроверено
Postimages postimg.cc ✅ (если есть расширение) ✅ ❌ Непроверено
lpic.cc lpic.cc/{code} ❌ (нет расширения) ❌ (не в белом списке, и нет расширения) ❌ ❌ (прямой ссылки просто нет)

По последней строке стоит сказать честно.

Работает ли lpic.cc для автооткрытия на PTT сейчас? Нет, и это текущее ограничение

Перед тем как писать эту статью, я заново проверил формат ссылок lpic.cc. URL, который получаешь после загрузки, сейчас выглядит как https://lpic.cc/{код} — это страница-визитка, а не прямая ссылка вроде i.imgur.com/xxx.jpg, заканчивающаяся расширением файла. Поэтому её не подхватывает ни правило по расширению www.ptt.cc, ни белые списки доменов term.ptt.cc и PttChrome. Сама страница показывает миниатюру, но только после открытия страницы, а не сразу при вставке ссылки в пост.

Честно говоря, для тех, кто хочет открывать картинки прямо на PTT, это не самая приятная новость, и я не собираюсь её приукрашивать. Если задача — вставить ссылку и получить автоматическую миниатюру, лучше подойдут хостинги с зелёной галочкой из таблицы выше (Imgur, meee, несколько сервисов из белого списка term.ptt.cc по умолчанию). Преимущество модели страницы-визитки вроде lpic.cc — в другом: защита паролем, счётчик просмотров, комментарии — это удобно, когда важно контролировать, «кто может смотреть и фиксируется ли просмотр»: например, скриншот сделки или личный контент, который вы отправляете со словами «открой по ссылке», а не выкладываете так, чтобы миниатюру автоматически видел любой прохожий. Это просто разные задачи, и попытка натянуть одну на другую только создаёт неудобства.

Так что же выбрать?

Если важно только то, чтобы «вставил ссылку — и сразу миниатюра», ориентируйтесь на основной клиент: для мобильного приложения — Imgur или meee (с привычкой дописывать расширение вручную); для чтения статей в веб-версии подойдёт любой хостинг со стандартным расширением в прямой ссылке, но помните — WebP в веб-версии www.ptt.cc не работает никогда; для term.ptt.cc сначала проверьте, есть ли нужный хостинг в вашем личном белом списке, если нет — добавьте вручную.

Если нужна ссылка, которая работает сразу на нескольких клиентах, Imgur пока остаётся единственным вариантом, подходящим под все четыре правила — правда, ценой является уже введённая блокировка IP-адресов Тайваня, об этом подробнее в полном гайде по публикации картинок на PTT. На самом деле нет ни одного хостинга, который избавил бы от головной боли с форматом во всех ситуациях сразу — я сам через это прошёл, и нет смысла делать реверансы в сторону кого-то одного.

Часто задаваемые вопросы

В1: Почему та же ссылка Imgur вчера открывалась, а сегодня нет?

Imgur блокирует IP-адреса Тайваня с мая 2025 года — если вы находитесь на Тайване, i.imgur.com может быть просто недоступен, и это не связано с правилами клиента PTT. Кроме того, PttChrome принудительно переписывает ссылки Imgur с расширением .jpg: если оригинал — PNG с прозрачным фоном, качество или прозрачность могут пострадать, но на сам факт открытия картинки это не влияет, только на то, как она выглядит.

В2: Можно ли самому менять список доверенных доменов в term.ptt.cc?

Судя по исходному коду, функция parseTrustedDomains поддерживает чтение пользовательского списка — значит, это настраиваемый параметр, а не жёстко зашитое правило. Где именно в интерфейсе это меняется и нужно ли перезагружать страницу, чтобы изменения вступили в силу, я сам не проверял на практике — лучше искать прямо в меню настроек term.ptt.cc.

В3: Почему у вас нет однозначного ответа про белый список доменов в мобильных приложениях?

Потому что Mo PTT, JPTT, PiTT — всё это закрытое ПО, публичного исходного кода для построчной проверки я не нашёл. Всё, что написано в статье об этих трёх приложениях, основано исключительно на отчётах сообщества с форумной секции ask, а не на моём собственном разборе кода — я уже пометил это как непроверенное в тексте и не собираюсь выдавать это за подтверждённый вывод.

В4: Почему www.ptt.cc не поддерживает WebP, а term.ptt.cc поддерживает?

Потому что это два полностью независимых кодовых базиса — один серверный на Go (pttweb), другой фронтенд на JavaScript (ptt-term), их поддерживают разные люди в разное время. WebP получил распространение относительно поздно, и правило pttweb, судя по всему, так и не обновили под него. Это, собственно, и есть главная мысль всей статьи: PTT — не единая система, а набор независимо поддерживаемых программ, собранных вместе с годами.

В5: Если нужна ссылка, которая открывается автоматически во всех клиентах PTT, какая комбинация ближе всего?

Единой ссылки на все случаи не существует, но ближе всего к этому: убедиться, что прямая ссылка хостинга заканчивается стандартным расширением (.jpg/.png/.gif, не полагаясь только на WebP), без query-строки, и выбирать хостинг, который уже есть в белом списке term.ptt.cc по умолчанию (Imgur, meee, duk.tw, ImgBB и Postimages — все в списке). У пользователей PttChrome выбор невелик — сейчас реально работают только Imgur и Flickr.

Источники

#PTT#term.ptt.cc#PttChrome#хостинг изображений#автопревью картинок#прямая ссылка на изображение#тайваньский форум#BBS
A

Автор

Alex Chen

Тестировщик продуктов

Практическое тестирование каждого инструмента с реальным опытом из первых уст.