/
Coderdev
/
web-nodejs-labs
Обзор
Документация
Войти
/
Coderdev
/
web-nodejs-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
public/lab12/task2/index.html
300 строк
18 KB
Coderdev
1
26 май 2026, 12:29
26 май 2026, 12:29
99f9df8
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ЛР12 — Тестирование Postman</title> <link rel="preconnect" href="https://fonts.googleapis.com"> <link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&display=swap" rel="stylesheet"> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Space Mono','Courier New',monospace; background: #fafafa; color: #1a1a1a; font-size: 13px; line-height: 1.6; } .wrap { max-width: 860px; margin: 0 auto; padding: 40px 20px 60px; } h1 { font-size: 18px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 8px; } .subtitle { font-size: 11px; color: #999; margin-bottom: 40px; } h2 { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 20px; padding-bottom: 8px; border-bottom: 2px solid #1a1a1a; } h3 { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; color: #555; margin-bottom: 12px; } .section { margin-bottom: 48px; } .test-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; } .test-card { border: 1px solid #e5e5e5; background: #fff; overflow: hidden; } .test-card-header { padding: 10px 14px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; display: flex; justify-content: space-between; align-items: center; } .test-card-header.ok { background: #f0faf4; border-bottom: 1px solid #27ae60; color: #27ae60; } .test-card-header.err { background: #fdf0f0; border-bottom: 1px solid #c0392b; color: #c0392b; } .test-card-header.warn { background: #fffbf0; border-bottom: 1px solid #e67e22; color: #e67e22; } .badge { display: inline-block; padding: 2px 8px; font-size: 10px; font-weight: 700; letter-spacing: 1px; } .badge.ok { background: #27ae60; color: #fff; } .badge.err { background: #c0392b; color: #fff; } .badge.warn { background: #e67e22; color: #fff; } .screenshot-slot { min-height: 200px; display: flex; flex-direction: column; align-items: center; justify-content: center; background: #f5f5f5; padding: 16px; text-align: center; } .screenshot-slot img { max-width: 100%; height: auto; display: block; } .screenshot-slot .placeholder-text { font-size: 10px; color: #bbb; text-transform: uppercase; letter-spacing: 1px; line-height: 1.8; } .request-info { padding: 12px 14px; font-size: 11px; border-bottom: 1px solid #f0f0f0; } .request-info code { background: #f5f5f5; padding: 2px 6px; font-family: inherit; font-size: 11px; } .method { display: inline-block; padding: 2px 8px; background: #1a1a1a; color: #fff; font-size: 10px; font-weight: 700; margin-right: 6px; } .note { font-size: 11px; color: #777; padding: 10px 14px; border-left: 3px solid #ddd; margin-bottom: 16px; } .note strong { color: #c0392b; } .back-link { margin-top: 40px; } .back-link a { font-size: 11px; color: #999; text-decoration: none; text-transform: uppercase; letter-spacing: 1px; } .back-link a:hover { color: #1a1a1a; } @media (max-width: 600px) { .test-grid { grid-template-columns: 1fr; } } </style> </head> <body> <div class="wrap"> <h1>Тестирование API — Postman</h1> <p class="subtitle">Скриншоты запросов к эндпойнтам лабораторной работы №12</p> <!-- ===== MANUAL CHECK ===== --> <div class="section"> <h2>Эндпойнт /manual-check</h2> <div class="note"> <span class="method">POST</span><code>http://localhost:3000/api/lab12/manual-check</code><br> Ручная проверка: сервер валидирует данные через <code>regexp.test()</code>. </div> <div class="test-grid"> <div class="test-card"> <div class="test-card-header ok"> <span>Успешный тест 1</span> <span class="badge ok">200 OK</span> </div> <div class="request-info"> Body: <code>{"fio":"Чуян Владислав Адреевич","recordBookNumber":"ПИ-2025-10","group":"ПИ-2401"}</code> </div> <div class="screenshot-slot"> <!-- Вставьте скриншот из Postman --> <img src="./img/manual-ok-1.png" alt="manual-check success 1" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>manual-ok-1.png </div> </div> </div> <div class="test-card"> <div class="test-card-header ok"> <span>Успешный тест 2</span> <span class="badge ok">200 OK</span> </div> <div class="request-info"> Body: <code>{"fio":"Петрова Анна-Мария","recordBookNumber":"ИТ-2022-5","group":"БИ-2303"}</code> </div> <div class="screenshot-slot"> <img src="./img/manual-ok-2.png" alt="manual-check success 2" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>manual-ok-2.png </div> </div> </div> <div class="test-card"> <div class="test-card-header err"> <span>Неуспешный тест 1</span> <span class="badge err">400</span> </div> <div class="request-info"> Body: <code>{"fio":"Chuyan Vladislav","recordBookNumber":"ПИ-2019-10","group":"ПИ-2401"}</code><br> Причина: ФИО не на русском </div> <div class="screenshot-slot"> <img src="./img/manual-err-1.png" alt="manual-check error 1" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>manual-err-1.png </div> </div> </div> <div class="test-card"> <div class="test-card-header err"> <span>Неуспешный тест 2</span> <span class="badge err">400</span> </div> <div class="request-info"> Body: <code>{"fio":"Chuyan Vladislav","recordBookNumber":"ПИ-2019-10","group":"ПИ-2401"}</code><br> Причина: год 2019 вне диапазона </div> <div class="screenshot-slot"> <img src="./img/manual-err-2.png" alt="manual-check error 2" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>manual-err-2.png </div> </div> </div> </div> </div> <!-- ===== SCHEMA CHECK ===== --> <div class="section"> <h2>Эндпойнт /schema-check</h2> <div class="note"> <span class="method">POST</span><code>http://localhost:3000/api/lab12/schema-check</code><br> Проверка через Fastify JSON Schema (AJV). Отклоняет даже лишние поля. </div> <div class="test-grid"> <div class="test-card"> <div class="test-card-header ok"> <span>Успешный тест 1</span> <span class="badge ok">200 OK</span> </div> <div class="request-info"> Body: <code>{"fio":"Сидоров Сидор","recordBookNumber":"БИ-2024-3","group":"ЭС-2402"}</code> </div> <div class="screenshot-slot"> <img src="./img/schema-ok-1.png" alt="schema-check success 1" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>schema-ok-1.png </div> </div> </div> <div class="test-card"> <div class="test-card-header ok"> <span>Успешный тест 2</span> <span class="badge ok">200 OK</span> </div> <div class="request-info"> Body: <code>{"fio":"Козлова-Иванова Мария","recordBookNumber":"ИТ-2021-99","group":"МХ-2204"}</code> </div> <div class="screenshot-slot"> <img src="./img/schema-ok-2.png" alt="schema-check success 2" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>schema-ok-2.png </div> </div> </div> <div class="test-card"> <div class="test-card-header err"> <span>Неуспешный тест 1</span> <span class="badge err">400</span> </div> <div class="request-info"> Body: <code>{"fio":"Иванов123","recordBookNumber":"ПИ-2025-1","group":"ПИ-2401"}</code><br> Причина: цифры в ФИО </div> <div class="screenshot-slot"> <img src="./img/schema-err-1.png" alt="schema-check error 1" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>schema-err-1.png </div> </div> </div> <div class="test-card"> <div class="test-card-header err"> <span>Неуспешный тест 2</span> <span class="badge err">400</span> </div> <div class="request-info"> Body: <code>{"fio":"Chuyan Vladislav","recordBookNumber":"ПИ-2025-1","group":"ПИ-2401","extra":"field"}</code><br> Причина: лишнее поле (additionalProperties: false) </div> <div class="screenshot-slot"> <img src="./img/schema-err-2.png" alt="schema-check error 2" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>schema-err-2.png </div> </div> </div> </div> </div> <!-- ===== NO CHECK — bypass demo ===== --> <div class="section"> <h2>Эндпойнт /no-check — обход валидации</h2> <div class="note"> <span class="method">POST</span><code>http://localhost:3000/api/lab12/no-check</code><br> <strong>Важно!</strong> Сервер принимает любые данные без проверки. Демонстрирует, почему фронтенд-валидации недостаточно. </div> <div class="test-grid"> <div class="test-card"> <div class="test-card-header warn"> <span>Обход 1 — невалидный год</span> <span class="badge warn">200</span> </div> <div class="request-info"> Body: <code>{"fio":"Ivan123!","recordBookNumber":"XX-1999-999","group":"ZZ-9999"}</code><br> Клиент бы отклонил, сервер принял </div> <div class="screenshot-slot"> <img src="./img/nocheck-bypass-1.png" alt="no-check bypass 1" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>nocheck-bypass-1.png </div> </div> </div> <div class="test-card"> <div class="test-card-header warn"> <span>Обход 2 — пустые поля</span> <span class="badge warn">200</span> </div> <div class="request-info"> Body: <code>{"fio":"","recordBookNumber":"","group":""}</code><br> Пустые данные приняты без ошибок </div> <div class="screenshot-slot"> <img src="./img/nocheck-bypass-2.png" alt="no-check bypass 2" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>nocheck-bypass-2.png </div> </div> </div> <div class="test-card"> <div class="test-card-header warn"> <span>Обход 3 — SQL injection</span> <span class="badge warn">200</span> </div> <div class="request-info"> Body: <code>{"fio":"'; DROP TABLE users; --","recordBookNumber":"ПИ-2025-1","group":"ПИ-2401"}</code><br> Вредоносные данные приняты без фильтрации </div> <div class="screenshot-slot"> <img src="./img/nocheck-bypass-3.png" alt="no-check bypass 3" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"> <div class="placeholder-text" style="display:flex;flex-direction:column;align-items:center;gap:8px"> <svg width="32" height="32" fill="none" stroke="#ccc" stroke-width="1.5" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg> Вставьте скриншот<br>nocheck-bypass-3.png </div> </div> </div> </div> <div class="note"> Вывод: фронтенд-валидация легко обходится прямыми запросами к API (через Postman, curl и т.д.). Надёжной считается только <strong>серверная</strong> валидация. </div> </div> <div class="back-link"><a href="/lab12/">← К списку заданий</a></div> </div> </body> </html>