# π Π€ΠΎΡΠΌΠ°Ρ URL Π΄Π»Ρ ΡΠ΅ΡΠ°ΠΉΠ·Π΅ΡΠ° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ
## ΠΠ±Π·ΠΎΡ
Quoter ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠ°Π·ΠΌΠ΅ΡΠ° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΡΠ΅ΡΠ΅Π· URL ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ. Π‘ΠΈΡΡΠ΅ΠΌΠ° Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅Ρ ΠΌΠΈΠ½ΠΈΠ°ΡΡΡΡ Π² ΠΏΡΠ΅Π΄ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΡ
ΡΠ°Π·ΠΌΠ΅ΡΠ°Ρ
ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π±Π»ΠΈΠΆΠ°ΠΉΡΠΈΠΉ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡΠΈΠΉ ΡΠ°Π·ΠΌΠ΅Ρ.
## π― ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΡΠ΅ ΡΠ°Π·ΠΌΠ΅ΡΡ
### ΠΡΠ΅Π΄ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠ΅ ΡΠΈΡΠΈΠ½Ρ
```rust
[10, 40, 110, 300, 600, 800, 1400] // ΠΏΠΈΠΊΡΠ΅Π»Π΅ΠΉ ΠΏΠΎ ΡΠΈΡΠΈΠ½Π΅
```
- **10px** - ΠΌΠΈΠΊΡΠΎ-ΠΏΡΠ΅Π²ΡΡ
- **40px** - Π°Π²Π°ΡΠ°ΡΡ, ΠΈΠΊΠΎΠ½ΠΊΠΈ
- **110px** - ΠΌΠ°Π»Π΅Π½ΡΠΊΠΈΠ΅ ΠΏΡΠ΅Π²ΡΡ
- **300px** - ΡΡΠ΅Π΄Π½ΠΈΠ΅ ΠΏΡΠ΅Π²ΡΡ
- **600px** - ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ
- **800px** - Π±ΠΎΠ»ΡΡΠΈΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ
- **1400px** - ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΡΠ°Π·ΠΌΠ΅Ρ
## π Π‘ΠΈΠ½ΡΠ°ΠΊΡΠΈΡ URL
### 1. Π‘ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ ΡΠΎΡΠΌΠ°Ρ (ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΡΡΡ)
```
GET /{filename}_{width}.{extension}
```
**ΠΡΠΈΠΌΠ΅ΡΡ:**
```bash
# ΠΠ°ΠΏΡΠΎΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΠΈΡΠΈΠ½ΠΎΠΉ 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}
```
**ΠΡΠΈΠΌΠ΅ΡΡ:**
```bash
# 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
```
**ΠΡΠΈΠΌΠ΅ΡΡ:**
```bash
# ΠΠΎΠ½Π²Π΅ΡΡΠΈΡ Π² WebP
GET /439efaa0-816f-11ef-b201-439da98539bc.jpg/webp
# ΠΠΎΠ½Π²Π΅ΡΡΠΈΡ Ρ ΡΠ΅ΡΠ°ΠΉΠ·ΠΎΠΌ
GET /439efaa0-816f-11ef-b201-439da98539bc_600.jpg/webp
```
## π§ ΠΠΎΠ³ΠΈΠΊΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ
### ΠΠ»Π³ΠΎΡΠΈΡΠΌ Π²ΡΠ±ΠΎΡΠ° ΡΠ°Π·ΠΌΠ΅ΡΠ°
1. **Π’ΠΎΡΠ½ΠΎΠ΅ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅**: ΠΡΠ»ΠΈ Π·Π°ΠΏΡΠΎΡΠ΅Π½Π½Π°Ρ ΡΠΈΡΠΈΠ½Π° Π΅ΡΡΡ Π² ΠΏΡΠ΅Π΄ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΡ
ΡΠ°Π·ΠΌΠ΅ΡΠ°Ρ
2. **ΠΠ»ΠΈΠΆΠ°ΠΉΡΠΈΠΉ ΡΠ°Π·ΠΌΠ΅Ρ**: ΠΡΠ±ΠΈΡΠ°Π΅ΡΡΡ ΡΠ°Π·ΠΌΠ΅Ρ Ρ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΉ ΡΠ°Π·Π½ΠΎΡΡΡΡ
3. **ΠΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ Π»ΠΈΠΌΠΈΡ**: ΠΡΠ»ΠΈ Π·Π°ΠΏΡΠΎΡΠ΅Π½Π½Π°Ρ ΡΠΈΡΠΈΠ½Π° > 1400px, Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ 1400px
4. **ΠΡΠΈΠ³ΠΈΠ½Π°Π»**: ΠΡΠ»ΠΈ ΡΠΈΡΠΈΠ½Π° Π½Π΅ ΡΠΊΠ°Π·Π°Π½Π° (0), Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΠΎΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅
### ΠΡΠΈΠΌΠ΅ΡΡ Π²ΡΠ±ΠΎΡΠ° ΡΠ°Π·ΠΌΠ΅ΡΠ°
```bash
# ΠΠ°ΠΏΡΠΎΡ 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 Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ
### ΠΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
```http
ETag: "filename.ext"
Cache-Control: public, max-age=31536000, immutable
Access-Control-Allow-Origin: *
```
### Π£ΡΠ»ΠΎΠ²Π½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ
```http
# ΠΠ»ΠΈΠ΅Π½Ρ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ
If-None-Match: "filename.ext"
# Π‘Π΅ΡΠ²Π΅Ρ ΠΎΡΠ²Π΅ΡΠ°Π΅Ρ (Π΅ΡΠ»ΠΈ Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ)
HTTP/1.1 304 Not Modified
```
## π‘ ΠΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ
### ΠΠ»ΠΈΠ΅Π½ΡΡΠΊΠ°Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ
```html
```
### API ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅
```javascript
// Π€ΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΎΠΏΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ³ΠΎ 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
```
## π ΠΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³ ΠΈ ΠΎΡΠ»Π°Π΄ΠΊΠ°
### ΠΠΎΠ³ΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ°
```log
# Π£ΡΠΏΠ΅ΡΠ½Π°Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ°
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
```bash
# ΠΡΠΎΠ²Π΅ΡΠΊΠ° ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°Π½ΠΈΡ ΡΠ°ΠΉΠ»Π°
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 Π΄Π»Ρ Π·Π°Π³ΡΡΠ·ΠΊΠΈ
### Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΠΈ
1. **ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ WebP** Π΄Π»Ρ Π»ΡΡΡΠ΅Π³ΠΎ ΡΠΆΠ°ΡΠΈΡ
2. **ΠΡΡΠΈΡΡΠΉΡΠ΅ Π½Π° CDN** Π΄Π»Ρ Π»ΡΡΡΠ΅ΠΉ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ
3. **Π£ΠΊΠ°Π·ΡΠ²Π°ΠΉΡΠ΅ ΡΠ°Π·ΠΌΠ΅ΡΡ Π·Π°ΡΠ°Π½Π΅Π΅** Π΄Π»Ρ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΡ layout shift
4. **ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ lazy loading** Π΄Π»Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π²Π½Π΅ viewport
### Troubleshooting
```bash
# ΠΡΠ»ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅ΡΡΡ
1. ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ ΡΠΎΡΠΌΠ°Ρ ΡΠ°ΠΉΠ»Π° (ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ Π»ΠΈ)
2. ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ ΡΠ°Π·ΠΌΠ΅Ρ Π·Π°ΠΏΡΠΎΡΠ° (Π½Π΅ ΠΏΡΠ΅Π²ΡΡΠ°Π΅Ρ Π»ΠΈ Π»ΠΈΠΌΠΈΡΡ)
3. ΠΡΠΎΠ²Π΅ΡΡΡΠ΅ Π»ΠΎΠ³ΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ° Π½Π° ΠΎΡΠΈΠ±ΠΊΠΈ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ
4. Π£Π±Π΅Π΄ΠΈΡΠ΅ΡΡ Π² ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΡΡΠΈ URL ΡΠΎΡΠΌΠ°ΡΠ°
```