You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/uk/7-bank-project/2-forms/README.md

28 KiB

Створення банківського додатку, частина 2: створення форми входу та реєстрації

Передлекційний тест

Передлекційний тест

Вступ

У майже всіх сучасних веб-додатках ви можете створити обліковий запис, щоб мати свій власний приватний простір. Оскільки кілька користувачів можуть одночасно отримувати доступ до веб-додатку, потрібен механізм для зберігання персональних даних кожного користувача окремо та вибору інформації для відображення. Ми не будемо розглядати, як безпечно керувати ідентифікацією користувачів, оскільки це окрема велика тема, але ми забезпечимо можливість створення одного (або кількох) банківських рахунків у нашому додатку.

У цій частині ми використаємо HTML-форми для додавання входу та реєстрації до нашого веб-додатку. Ми розглянемо, як програмно надсилати дані на серверний API, і зрештою визначимо базові правила валідації для введення користувачем даних.

Передумови

Вам потрібно завершити шаблони HTML та маршрутизацію веб-додатку для цього уроку. Також необхідно встановити Node.js і запустити серверний API локально, щоб ви могли надсилати дані для створення облікових записів.

Зверніть увагу
Ви будете використовувати два термінали одночасно, як зазначено нижче:

  1. Для основного банківського додатку, який ми створили в уроці шаблони HTML та маршрутизація.
  2. Для серверного API банківського додатку, який ми щойно налаштували вище.

Вам потрібно, щоб обидва сервери працювали одночасно для подальшого проходження уроку. Вони слухають на різних портах (порт 3000 і порт 5000), тому все має працювати без проблем.

Ви можете перевірити, чи сервер працює належним чином, виконавши цю команду в терміналі:

curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result

Форма та елементи керування

Елемент <form> інкапсулює розділ HTML-документа, де користувач може вводити та надсилати дані за допомогою інтерактивних елементів керування. Існує багато різних елементів інтерфейсу користувача (UI), які можна використовувати у формі, найпоширенішими з яких є елементи <input> і <button>.

Існує багато різних типів <input>. Наприклад, щоб створити поле, де користувач може ввести своє ім'я користувача, ви можете використати:

<input id="username" name="username" type="text">

Атрибут name буде використовуватися як ім'я властивості, коли дані форми будуть надіслані. Атрибут id використовується для зв’язування <label> з елементом керування формою.

Ознайомтеся з повним списком типів <input> і інших елементів керування формами, щоб отримати уявлення про всі доступні елементи інтерфейсу користувача, які ви можете використовувати під час створення вашого інтерфейсу.

Зверніть увагу, що <input> є порожнім елементом, до якого не слід додавати закриваючий тег. Ви можете використовувати самозакриваючий запис <input/>, але це не обов’язково.

Елемент <button> у формі має особливу поведінку. Якщо ви не вкажете його атрибут type, він автоматично надішле дані форми на сервер при натисканні. Ось можливі значення атрибута type:

  • submit: За замовчуванням у <form>, кнопка викликає дію надсилання форми.
  • reset: Кнопка скидає всі елементи керування форми до їх початкових значень.
  • button: Не призначає жодної поведінки за замовчуванням при натисканні кнопки. Ви можете призначити їй власні дії за допомогою JavaScript.

Завдання

Давайте почнемо з додавання форми до шаблону login. Нам знадобиться поле для імені користувача та кнопка Login.

<template id="login">
  <h1>Bank App</h1>
  <section>
    <h2>Login</h2>
    <form id="loginForm">
      <label for="username">Username</label>
      <input id="username" name="user" type="text">
      <button>Login</button>
    </form>
  </section>
</template>

Якщо придивитися, ви помітите, що ми також додали елемент <label>. Елементи <label> використовуються для додавання назви до елементів керування інтерфейсу користувача, таких як наше поле для імені користувача. Мітки важливі для зручності читання ваших форм, а також мають додаткові переваги:

  • Зв’язуючи мітку з елементом керування формою, це допомагає користувачам, які використовують допоміжні технології (наприклад, екранний диктор), зрозуміти, які дані від них очікуються.
  • Ви можете натиснути на мітку, щоб безпосередньо сфокусуватися на пов’язаному полі введення, що полегшує доступ на пристроях із сенсорним екраном.

Доступність у вебі — це дуже важлива тема, яку часто ігнорують. Завдяки семантичним HTML-елементам створювати доступний контент не складно, якщо використовувати їх належним чином. Ви можете дізнатися більше про доступність, щоб уникнути поширених помилок і стати відповідальним розробником.

Тепер ми додамо другу форму для реєстрації, одразу під попередньою:

<hr/>
<h2>Register</h2>
<form id="registerForm">
  <label for="user">Username</label>
  <input id="user" name="user" type="text">
  <label for="currency">Currency</label>
  <input id="currency" name="currency" type="text" value="$">
  <label for="description">Description</label>
  <input id="description" name="description" type="text">
  <label for="balance">Current balance</label>
  <input id="balance" name="balance" type="number" value="0">
  <button>Register</button>
</form>

Використовуючи атрибут value, ми можемо визначити значення за замовчуванням для певного поля введення. Зверніть увагу, що поле введення для balance має тип number. Чи виглядає воно інакше, ніж інші поля? Спробуйте взаємодіяти з ним.

Чи можете ви навігувати та взаємодіяти з формами, використовуючи лише клавіатуру? Як би ви це зробили?

Надсилання даних на сервер

Тепер, коли у нас є функціональний інтерфейс, наступний крок — надіслати дані на сервер. Давайте швидко протестуємо наш поточний код: що відбувається, якщо ви натискаєте кнопку Login або Register?

Чи помітили ви зміну в адресному рядку вашого браузера?

Знімок екрана зі зміною URL браузера після натискання кнопки Register

Дія за замовчуванням для <form> — це надсилання форми на поточну URL-адресу сервера за допомогою методу GET, додаючи дані форми безпосередньо до URL. Однак цей метод має кілька недоліків:

  • Обсяг даних, що надсилаються, дуже обмежений (приблизно 2000 символів).
  • Дані безпосередньо видно в URL (що не дуже добре для паролів).
  • Він не працює з завантаженням файлів.

Саме тому ви можете змінити його на використання методу POST, який надсилає дані форми на сервер у тілі HTTP-запиту, без жодних попередніх обмежень.

Хоча POST є найпоширенішим методом для надсилання даних, у деяких конкретних сценаріях краще використовувати метод GET, наприклад, під час реалізації поля пошуку.

Завдання

Додайте властивості action і method до форми реєстрації:

<form id="registerForm" action="//localhost:5000/api/accounts" method="POST">

Тепер спробуйте зареєструвати новий обліковий запис зі своїм ім’ям. Після натискання кнопки Register ви повинні побачити щось подібне:

Вікно браузера на адресі localhost:5000/api/accounts, що показує JSON-рядок із даними користувача

Якщо все працює правильно, сервер повинен відповісти на ваш запит JSON-відповіддю, що містить дані створеного облікового запису.

Спробуйте зареєструватися знову з тим самим ім’ям. Що відбувається?

Надсилання даних без перезавантаження сторінки

Як ви, мабуть, помітили, є невелика проблема з підходом, який ми щойно використали: під час надсилання форми ми виходимо з нашого додатку, і браузер перенаправляє на URL сервера. Ми намагаємося уникнути всіх перезавантажень сторінок у нашому веб-додатку, оскільки створюємо односторінковий додаток (SPA).

Щоб надіслати дані форми на сервер без примусового перезавантаження сторінки, нам потрібно використовувати JavaScript. Замість того, щоб вказувати URL у властивості action елемента <form>, ви можете використовувати будь-який JavaScript-код, додавши перед ним рядок javascript:, щоб виконати власну дію. Це також означає, що вам доведеться реалізувати деякі завдання, які раніше автоматично виконував браузер:

  • Отримання даних форми.
  • Конвертація та кодування даних форми у відповідний формат.
  • Створення HTTP-запиту та його надсилання на сервер.

Завдання

Замініть action форми реєстрації на:

<form id="registerForm" action="javascript:register()">

Відкрийте app.js і додайте нову функцію з назвою register:

function register() {
  const registerForm = document.getElementById('registerForm');
  const formData = new FormData(registerForm);
  const data = Object.fromEntries(formData);
  const jsonData = JSON.stringify(data);
}

Тут ми отримуємо елемент форми за допомогою getElementById() і використовуємо помічник FormData, щоб витягти значення з елементів керування форми у вигляді набору пар ключ/значення. Потім ми конвертуємо дані у звичайний об’єкт за допомогою Object.fromEntries() і, нарешті, серіалізуємо дані у формат JSON, який зазвичай використовується для обміну даними в Інтернеті.

Дані тепер готові до надсилання на сервер. Створіть нову функцію з назвою createAccount:

async function createAccount(account) {
  try {
    const response = await fetch('//localhost:5000/api/accounts', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: account
    });
    return await response.json();
  } catch (error) {
    return { error: error.message || 'Unknown error' };
  }
}

Що робить ця функція? По-перше, зверніть увагу на ключове слово async. Це означає, що функція містить код, який виконуватиметься асинхронно. Коли використовується разом із ключовим словом await, це дозволяє чекати виконання асинхронного коду — наприклад, очікування відповіді сервера — перед продовженням.

Ось коротке відео про використання async/await:

Async і Await для керування промісами

🎥 Натисніть на зображення вище, щоб переглянути відео про async/await.

Ми використовуємо API fetch() для надсилання JSON-даних на сервер. Цей метод приймає 2 параметри:

  • URL сервера, тому ми вказуємо //localhost:5000/api/accounts.
  • Налаштування запиту. Тут ми встановлюємо метод POST і надаємо body для запиту. Оскільки ми надсилаємо JSON-дані на сервер, нам також потрібно встановити заголовок Content-Type у значення application/json, щоб сервер знав, як інтерпретувати вміст.

Оскільки сервер відповість на запит JSON-даними, ми можемо використовувати await response.json(), щоб розібрати JSON-вміст і повернути отриманий об’єкт. Зверніть увагу, що цей метод є асинхронним, тому ми використовуємо ключове слово await, щоб переконатися, що будь-які помилки під час розбору також будуть враховані.

Тепер додайте трохи коду до функції register, щоб викликати createAccount():

const result = await createAccount(jsonData);

Оскільки ми використовуємо ключове слово await, нам потрібно додати ключове слово async перед функцією register:

async function register() {

Нарешті, додамо кілька логів, щоб перевірити результат. Остаточна функція має виглядати так:

async function register() {
  const registerForm = document.getElementById('registerForm');
  const formData = new FormData(registerForm);
  const jsonData = JSON.stringify(Object.fromEntries(formData));
  const result = await createAccount(jsonData);

  if (result.error) {
    return console.log('An error occurred:', result.error);
  }

  console.log('Account created!', result);
}

Це було трохи довго, але ми впоралися! Якщо ви відкриєте інструменти розробника браузера і спробуєте зареєструвати новий обліковий запис, ви не побачите жодних змін на веб-сторінці, але в консолі з’явиться повідомлення, яке підтверджує, що все працює.

Знімок екрана з повідомленням у консолі браузера

Як ви думаєте, чи дані надсилаються на сервер безпечно? Що, якщо хтось зможе перехопити запит? Ви можете прочитати про HTTPS, щоб дізнатися більше про безпечну передачу даних.

Валідація даних

Якщо ви спробуєте зареєструвати новий обліковий запис, не вказавши спочатку ім’я користувача, ви побачите, що сервер повертає помилку зі статус-кодом 400 (Bad Request).

Перед надсиланням даних на сервер гарною практикою є перевірка даних форми заздалегідь, щоб переконатися, що ви надсилаєте дійсний запит. HTML5 елементи керування формами забезпечують вбудовану валідацію за допомогою різних атрибутів:

  • required: поле має бути заповнене, інакше форму не можна надіслати.
  • minlength і maxlength: визначають мінімальну та максимальну кількість символів у текстових полях.
  • min і max: визначають мінімальне та максимальне значення числового поля.
  • type: визначає тип очікуваних даних, наприклад, number, email, file або інші вбудовані типи. Цей атрибут також може змінювати візуальне відображення елемента керування.
  • pattern: дозволяє визначити регулярний вираз для перевірки, чи введені дані є дійсними. Порада: ви можете налаштувати вигляд елементів керування формою залежно від того, чи вони є валідними, чи ні, використовуючи псевдокласи CSS :valid та :invalid.

Завдання

Для створення нового облікового запису необхідно заповнити два обов’язкові поля: ім’я користувача та валюту. Інші поля є необов’язковими. Оновіть HTML форми, використовуючи атрибут required і текст у мітці поля, щоб це виглядало так:

<label for="user">Username (required)</label>
<input id="user" name="user" type="text" required>
...
<label for="currency">Currency (required)</label>
<input id="currency" name="currency" type="text" value="$" required>

Хоча ця конкретна серверна реалізація не накладає жорстких обмежень на максимальну довжину полів, завжди є гарною практикою визначати розумні межі для будь-якого текстового вводу користувача.

Додайте атрибут maxlength до текстових полів:

<input id="user" name="user" type="text" maxlength="20" required>
...
<input id="currency" name="currency" type="text" value="$" maxlength="5" required>
...
<input id="description" name="description" type="text" maxlength="100">

Тепер, якщо ви натиснете кнопку Зареєструватися, і якесь поле не відповідатиме визначеним нами правилам валідації, ви побачите щось подібне:

Знімок екрана, що показує помилку валідації при спробі надіслати форму

Валідація, яка виконується до надсилання будь-яких даних на сервер, називається клієнтською валідацією. Але зверніть увагу, що не завжди можливо виконати всі перевірки без надсилання даних. Наприклад, ми не можемо перевірити тут, чи існує вже обліковий запис із таким самим ім’ям користувача, без запиту до сервера. Додаткова валідація, яка виконується на сервері, називається серверною валідацією.

Зазвичай потрібно реалізовувати обидва типи валідації. Клієнтська валідація покращує взаємодію з користувачем, надаючи миттєвий зворотний зв’язок, але серверна валідація є критично важливою для забезпечення коректності та безпеки даних користувача.


🚀 Виклик

Показуйте повідомлення про помилку в HTML, якщо користувач уже існує.

Ось приклад того, як може виглядати фінальна сторінка входу після невеликого стилізування:

Знімок екрана сторінки входу після додавання стилів CSS

Післялекційний тест

Післялекційний тест

Огляд і самостійне навчання

Розробники проявляють неабияку креативність у створенні форм, особливо щодо стратегій валідації. Дізнайтеся про різні підходи до створення форм, переглядаючи CodePen; чи зможете ви знайти цікаві та надихаючі приклади форм?

Завдання

Стилізуйте свій банківський додаток


Відмова від відповідальності:
Цей документ був перекладений за допомогою сервісу автоматичного перекладу Co-op Translator. Хоча ми прагнемо до точності, будь ласка, майте на увазі, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ на його рідній мові слід вважати авторитетним джерелом. Для критичної інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникають внаслідок використання цього перекладу.