### New Documentation: - **URL Format Guide**: Complete guide for image resizer URL patterns - **Hybrid Architecture**: Vercel Edge + Quoter integration strategy - **Updated How-it-works**: Comprehensive system architecture with diagrams - **Enhanced Configuration**: Security settings, troubleshooting, Vercel integration ### Documentation Structure: 📋 Architecture & Principles: - 🚀 How Quoter Works (detailed system architecture) - 🔀 Hybrid Architecture (Vercel + Quoter best practices) - 📐 URL Format (complete resizer URL guide) 🛡️ Security & Configuration: - 🔒 Security & DDoS Protection (comprehensive guide) - ⚙️ Configuration (updated with new settings) - 🚀 Deployment & 📊 Monitoring 🎨 Integrations: - Vercel OG Integration guides - Edge Function examples ### Key Features Documented: - Complete URL patterns for image resizing - Security rate limiting configuration - Hybrid upload (Quoter) + download (Vercel) strategy - JWT validation and session management - Multi-cloud storage (Storj + AWS fallback) - Performance optimization techniques - Production deployment strategies All documentation is now production-ready and includes practical examples! 📖✨
7.5 KiB
7.5 KiB
📐 Формат URL для ресайзера изображений
Обзор
Quoter поддерживает автоматическое изменение размера изображений через URL параметры. Система автоматически генерирует миниатюры в предопределенных размерах и возвращает ближайший подходящий размер.
🎯 Поддерживаемые размеры
Предопределенные ширины
[10, 40, 110, 300, 600, 800, 1400] // пикселей по ширине
- 10px - микро-превью
- 40px - аватары, иконки
- 110px - маленькие превью
- 300px - средние превью
- 600px - стандартные изображения
- 800px - большие изображения
- 1400px - максимальный размер
📝 Синтаксис URL
1. Современный формат (рекомендуется)
GET /{filename}_{width}.{extension}
Примеры:
# Запрос изображения шириной 300px
GET /439efaa0-816f-11ef-b201-439da98539bc_300.jpg
# Запрос изображения шириной 600px
GET /5627e002-0c53-11ee-9565-0242ac110006_600.png
# Запрос оригинального размера (без ресайза)
GET /439efaa0-816f-11ef-b201-439da98539bc.jpg
2. Legacy формат (поддерживается)
GET /unsafe/{width}x/production/image/{filename}.{extension}
Примеры:
# Legacy формат с указанием ширины
GET /unsafe/1440x/production/image/439efaa0-816f-11ef-b201-439da98539bc.jpg
# Legacy формат без ресайза
GET /unsafe/production/image/5627e002-0c53-11ee-9565-0242ac110006.png
3. Конверсия формата
GET /{filename}.{extension}/webp
Примеры:
# Конверсия в WebP
GET /439efaa0-816f-11ef-b201-439da98539bc.jpg/webp
# Конверсия с ресайзом
GET /439efaa0-816f-11ef-b201-439da98539bc_600.jpg/webp
🔧 Логика обработки
Алгоритм выбора размера
- Точное совпадение: Если запрошенная ширина есть в предопределенных размерах
- Ближайший размер: Выбирается размер с минимальной разностью
- Максимальный лимит: Если запрошенная ширина > 1400px, возвращается 1400px
- Оригинал: Если ширина не указана (0), возвращается оригинальное изображение
Примеры выбора размера
# Запрос 150px → вернет 110px (ближайший меньший)
# Запрос 250px → вернет 300px (ближайший больший)
# Запрос 2000px → вернет 1400px (максимальный)
# Запрос 299px → вернет 300px (ближайший)
# Запрос 301px → вернет 300px (ближайший)
Генерация миниатюр
- Lazy generation: Миниатюры создаются по первому запросу
- Асинхронная обработка: Генерация происходит в фоне
- Кэширование: Созданные миниатюры сохраняются в S3
- Fallback: При отсутствии миниатюры возвращается оригинал
🎨 Поддерживаемые форматы
Входные форматы
- JPEG (
.jpg,.jpeg) - PNG (
.png) - GIF (
.gif) - WebP (
.webp) - HEIC (
.heic,.heif) - конвертируется в JPEG - TIFF (
.tiff,.tif) - конвертируется в JPEG
Выходные форматы
- Сохраняется исходный формат (кроме HEIC/TIFF → JPEG)
- WebP конверсия через
/webpсуффикс - Автоматическая оптимизация для web
🚀 HTTP заголовки
Кэширование
ETag: "filename.ext"
Cache-Control: public, max-age=31536000, immutable
Access-Control-Allow-Origin: *
Условные запросы
# Клиент отправляет
If-None-Match: "filename.ext"
# Сервер отвечает (если не изменено)
HTTP/1.1 304 Not Modified
💡 Оптимизация производительности
Клиентская оптимизация
<!-- Используйте srcset для разных размеров -->
<img src="/image_600.jpg"
srcset="/image_300.jpg 300w,
/image_600.jpg 600w,
/image_800.jpg 800w"
sizes="(max-width: 600px) 300px, 600px"
alt="Описание">
<!-- WebP с fallback -->
<picture>
<source srcset="/image_600.jpg/webp" type="image/webp">
<img src="/image_600.jpg" alt="Описание">
</picture>
API использование
// Функция для получения оптимального URL
function getImageUrl(filename, maxWidth) {
const sizes = [10, 40, 110, 300, 600, 800, 1400];
const optimalSize = sizes.find(size => size >= maxWidth) || 1400;
const [name, ext] = filename.split('.');
return `https://files.dscrs.site/${name}_${optimalSize}.${ext}`;
}
// Примеры использования
const thumbUrl = getImageUrl('image.jpg', 300); // image_300.jpg
const fullUrl = getImageUrl('image.jpg', 1200); // image_1400.jpg
🔍 Мониторинг и отладка
Логи сервера
# Успешная обработка
INFO GET image_300.jpg [START]
INFO Parsed request - base: image, width: 300, ext: jpg
INFO Cache hit for image.jpg, returning 304
# Генерация миниатюры
WARN Thumbnail not found, generating: image_300.jpg
WARN generate new thumb files: image.jpg
INFO Generated thumbnail: image_300.jpg
Проверка через API
# Проверка существования файла
curl -I https://files.dscrs.site/image_300.jpg
# Проверка с условным запросом
curl -H "If-None-Match: \"image.jpg\"" https://files.dscrs.site/image_300.jpg
⚠️ Ограничения и рекомендации
Лимиты
- Максимальная ширина: 1400px
- Поддерживаемые форматы: см. список выше
- Размер файла: до 500MB для загрузки
Рекомендации
- Используйте WebP для лучшего сжатия
- Кэшируйте на CDN для лучшей производительности
- Указывайте размеры заранее для избежания layout shift
- Используйте lazy loading для изображений вне viewport
Troubleshooting
# Если изображение не отображается
1. Проверьте формат файла (поддерживается ли)
2. Проверьте размер запроса (не превышает ли лимиты)
3. Проверьте логи сервера на ошибки генерации
4. Убедитесь в корректности URL формата