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/bg/7-bank-project/2-forms
leestott c0ca49b2cc
🌐 Update translations via Co-op Translator
3 weeks ago
..
README.md 🌐 Update translations via Co-op Translator 3 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 3 weeks ago

README.md

Създаване на Банкова Приложение Част 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> типове и други контроли на формуляри, за да получите представа за всички налични UI елементи, които можете да използвате при изграждането на вашия интерфейс.

Забележете, че <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> се използват за добавяне на име към UI контроли, като нашето поле за потребителско име. Етикетите са важни за четимостта на вашите формуляри, но също така идват с допълнителни предимства:

  • Асоциирането на етикет с контрола на формуляра помага на потребителите, използващи асистивни технологии (като екранен четец), да разберат какви данни се очаква да предоставят.
  • Можете да кликнете върху етикета, за да поставите директно фокус върху свързаното поле, което улеснява достъпа на устройства с тъчскрийн.

Достъпността в уеб пространството е много важна тема, която често се пренебрегва. Благодарение на семантичните 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 на вашия браузър?

Снимка на екрана, показваща промяна в 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.

Задача

Има 2 задължителни полета за създаване на валиден нов акаунт: потребителско име и валута, като останалите полета са по избор. Актуализирайте 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; можете ли да намерите интересни и вдъхновяващи формуляри?

Задание

Стилизирайте вашето банково приложение


Отказ от отговорност:
Този документ е преведен с помощта на AI услуга за превод Co-op Translator. Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия изходен език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален превод от човек. Ние не носим отговорност за каквито и да е недоразумения или погрешни интерпретации, произтичащи от използването на този превод.