иконка discount

Скидка 15% по промокоду

кибер понедельник до 01.12иконка discount
CYBER2025
логотип PurpleSchool
логотип PurpleSchool

Атрибут method в HTML - как правильно отправлять данные формы

Автор

Олег Марков

Введение

Атрибут method в HTML отвечает за то, как браузер отправит данные формы на сервер. От выбора значения этого атрибута зависит:

  • куда попадут данные – в URL или в тело запроса
  • какие ограничения по размеру будут у отправляемых данных
  • как сервер сможет эти данные прочитать
  • как поведут себя кэширование, история браузера и закладки
  • какие риски безопасности появятся

Если вы работаете с веб-формами, то атрибут method – один из ключевых инструментов. Смотрите, я покажу вам, как он устроен, какие значения поддерживает HTML, чем отличаются GET и POST на практике, и как избежать типичных ошибок при выборе метода.

Что такое атрибут method в HTML

Базовое определение

Атрибут method задается у тега формы:

<form action="/search" method="get">
  <!-- Поля формы -->
</form>

Основная идея:

  • тег <form> описывает структуру данных, которые вы хотите отправить
  • атрибут action указывает, куда отправить данные (URL)
  • атрибут method говорит, как отправить данные (HTTP-метод запроса)

Если вы не зададите method явно, браузер будет вести себя так, как описано в спецификации: для тегов <form> по умолчанию используется метод GET.

Поддерживаемые значения method

На практике чаще всего вы используете:

  • GET
  • POST

Но HTML также позволяет указать:

  • dialog
  • а также другие HTTP-методы (PUT, DELETE, PATCH и т.д.) через HTML5, хотя их реальная поддержка браузерами и серверной логикой ограничена и используется редко.

Давайте разберемся с основными методами подробнее.

Метод GET

Как работает GET для формы

Когда вы указываете method="get", данные формы кодируются в строку запроса и добавляются к URL после символа ?.

Пример:

<form action="/search" method="get">
  <!-- Поле для строки поиска -->
  <input type="text" name="q" />
  <!-- Кнопка отправки формы -->
  <button type="submit">Найти</button>
</form>

Если пользователь введет в поле значение:

  • q = html method

то браузер отправит запрос примерно такого вида:

GET /search?q=html+method HTTP/1.1
Host: example.com

Комментарии:

  • строка ?q=html+method – это параметры запроса
  • пробелы кодируются в + или %20
  • любые спецсимволы в значениях полей формы будут URL-кодированы

Где хранится тело данных при GET

При GET нет тела запроса с данными формы. Весь набор полей попадает:

  • в URL (query string)
  • в логи сервера (где логируется вся строка запроса)
  • в историю браузера
  • в адресную строку, которую легко скопировать, переслать или добавить в закладки

Поэтому GET очень удобен, когда данные:

  • не чувствительные
  • небольшие по объему
  • описывают "запрос" к ресурсу, а не изменение данных

Когда использовать GET

Давайте перечислим типичные случаи, когда method="get" – это правильный выбор:

  1. Поисковые формы

    • строка поиска
    • фильтрация товаров, статей, пользователей
    • сортировка и пагинация

    Пример:

    <form action="/products" method="get">
      <!-- Фильтр по категории -->
      <select name="category">
        <option value="">Все</option>
        <option value="phones">Телефоны</option>
        <option value="laptops">Ноутбуки</option>
      </select>
    
      <!-- Фильтр по минимальной цене -->
      <input type="number" name="price_min" placeholder="От" />
    
      <!-- Кнопка применения фильтра -->
      <button type="submit">Фильтровать</button>
    </form>

    Здесь вы легко можете поделиться ссылкой: /products?category=phones&price_min=10000.

  2. Операции чтения (идемпотентные запросы)

    GET подходит, когда:

    • вы не изменяете данные на сервере
    • повторный запрос не меняет результат (например, просмотр профиля, просмотр списка товаров, поиск)
  3. Страницы, которые нужно кэшировать

    Браузеры и прокси могут кэшировать результаты GET-запросов. Это улучшает производительность при:

    • переходах назад-вперед
    • повторных поисках
    • одинаковых фильтрах

Ограничения метода GET

Теперь давайте аккуратно разберем ограничения.

Ограничение длины URL

Каждый браузер и сервер накладывает ограничение на длину URL. Жесткого стандарта нет, но:

  • на практике стоит считать безопасной длиной до 2000–4000 символов
  • для сложных форм с массивами данных GET становится непрактичным

Смотрите, к чему это ведет:

  • большие текстовые поля (комментарии, описания) через GET передавать нельзя
  • вложенные структуры, длинные JSON-строки – тоже плохая идея

Проблемы с безопасностью

Основная проблема GET – данные видны в:

  • адресной строке
  • истории браузера
  • логах сервера и промежуточных прокси
  • сервисах аналитики (если URL туда попадают)

Поэтому через GET запрещено передавать:

  • пароли
  • токены аутентификации
  • персональные данные (паспортные данные, номера карт и т.п.)
  • любые чувствительные значения

Кэширование и повтор запросов

GET-запросы могут кэшироваться:

  • браузером
  • прокси
  • CDN

Это удобно для поиска или фильтрации, но:

  • повторный запрос GET может не дойти до сервера
  • пользователь при нажатии "Назад" может увидеть кэшированный результат
  • промежуточные узлы видят все параметры в URL

Обработка GET на сервере

Форматы зависят от языка, но общая идея одна – данные формы при GET попадают в набор параметров строки запроса.

Давайте посмотрим пример на PHP:

<?php
// Получаем значение поля q из параметров GET
$search = $_GET['q'] ?? ''; // Если параметр не передан, используем пустую строку
?>

И пример на Node.js (Express):

// Обрабатываем GET-запрос на /search
app.get('/search', (req, res) => {
  // Получаем параметр q из строки запроса
  const search = req.query.q || ''; // Если q нет - берем пустую строку

  // Дальше выполняем поиск и отправляем результат
  res.send(`Результаты поиска для: ${search}`);
});

Метод POST

Как работает POST для формы

Когда вы указываете method="post", данные формы отправляются в теле HTTP-запроса, а не в URL.

Пример:

<form action="/login" method="post">
  <!-- Поле для логина -->
  <input type="text" name="username" />
  <!-- Поле для пароля -->
  <input type="password" name="password" />
  <!-- Кнопка входа -->
  <button type="submit">Войти</button>
</form>

Запрос будет выглядеть примерно так:

POST /login HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

username=admin&password=secret123

Комментарии:

  • данные скрыты из строки URL, но не зашифрованы сами по себе
  • важно использовать HTTPS, чтобы скрыть содержимое тела запроса от перехвата в сети

Когда использовать POST

Давайте сформируем четкие критерии:

  1. Запросы, изменяющие данные на сервере

    Используйте POST для:

    • регистрации пользователей
    • изменения профиля
    • добавления или удаления записей
    • оформления заказа
    • всех операций, которые что-то меняют в базе или на сервере
  2. Передача чувствительных данных

    Только в сочетании с HTTPS, но все равно:

    • пароли
    • токены
    • конфиденциальные поля
    • большие текстовые сообщения
  3. Большие объемы данных

    POST позволяет отправить:

    • большие формы
    • длинные тексты
    • файлы (в сочетании с enctype="multipart/form-data")

    Здесь как раз нет строгого ограничения длины, как у URL, но сервер может иметь собственные лимиты на размер тела запроса.

Отличия POST от GET с точки зрения HTTP

Давайте систематизируем:

  • Где хранятся данные

    • GET – в URL (строка запроса)
    • POST – в теле запроса
  • Максимальный размер

    • GET – ограничен длиной URL
    • POST – ограничен настройками сервера (обычно заметно выше)
  • Кэширование

    • GET – может кэшироваться
    • POST – обычно не кэшируется
  • Повторяемость

    • GET – запрос может безопасно повторяться (если вы не сломали идею HTTP)
    • POST – может приводить к повторному созданию/изменению ресурсов (например, двойная отправка заказа)
  • История браузера

    • GET – параметры сохраняются в истории
    • POST – повторная отправка через форму подтверждения ("Повторно отправить данные формы?")

Примеры использования POST

Давайте посмотрим, как POST применяют в реальных задачах.

Регистрация пользователя

<form action="/signup" method="post">
  <!-- Имя пользователя -->
  <input type="text" name="username" required />
  <!-- Email пользователя -->
  <input type="email" name="email" required />
  <!-- Пароль -->
  <input type="password" name="password" required />
  <!-- Кнопка регистрации -->
  <button type="submit">Зарегистрироваться</button>
</form>

Комментарии:

  • здесь нельзя использовать GET, так как пароль окажется в URL
  • данные регистрации изменяют состояние системы (создают пользователя)

Загрузка файла

<form action="/upload" method="post" enctype="multipart/form-data">
  <!-- Поле для выбора файла -->
  <input type="file" name="file" />
  <!-- Кнопка отправки файла -->
  <button type="submit">Загрузить</button>
</form>

Комментарии:

  • здесь используется POST, так как только он позволяет корректно передать бинарные данные файлов
  • атрибут enctype управляет форматом кодирования тела запроса
  • GET в сочетании с файлами не работает

Обработка POST на сервере

Механика зависит от языка, но общая схема:

  • данные берутся из тела запроса
  • их нужно распарсить в зависимости от Content-Type

Пример на PHP:

<?php
// Получаем данные формы из POST
$username = $_POST['username'] ?? ''; // Логин
$password = $_POST['password'] ?? ''; // Пароль

// Здесь можно провести аутентификацию пользователя
?>

Пример на Node.js (Express, с использованием body-parser / встроенного парсера):

// Включаем парсер urlencoded-данных форм
app.use(express.urlencoded({ extended: false }));

// Обрабатываем POST-запрос на /login
app.post('/login', (req, res) => {
  // Получаем поля формы из тела запроса
  const username = req.body.username; // Логин
  const password = req.body.password; // Пароль

  // Здесь выполняем проверку логина и пароля
  res.send('Обработка входа');
});

Другие значения атрибута method

Значение dialog

HTML5 ввел элемент <dialog> и метод submit для форм, встроенных в диалог.

Атрибут method может принимать значение dialog:

<dialog id="myDialog">
  <form method="dialog">
    <!-- Поле ввода имени -->
    <input name="username" />
    <!-- Кнопка подтверждения -->
    <button value="ok">Ок</button>
    <!-- Кнопка отмены -->
    <button value="cancel">Отмена</button>
  </form>
</dialog>

Как это работает:

  • такая форма не отправляет данные на сервер
  • она просто "закрывает" диалог
  • значение кнопки (value) можно прочитать в JavaScript как результат диалога

Пример JavaScript-кода:

// Находим диалог по id
const dialog = document.getElementById('myDialog');

// Открываем диалог
dialog.showModal();

// Слушаем событие закрытия
dialog.addEventListener('close', () => {
  // Значение возврата (value у нажатой кнопки)
  const result = dialog.returnValue; // ok или cancel

  // Здесь можно обработать результат
});

Комментарии:

  • method="dialog" не относится к HTTP-методам
  • он используется только для внутренней логики диалога в браузере
  • запрос на сервер при этом не отправляется

Другие HTTP-методы (PUT, DELETE и т.д.)

Спецификация HTML разрешает указывать в method не только GET/POST, но и:

  • PUT
  • DELETE
  • PATCH
  • другие строковые значения

Но давайте посмотрим на практику:

  • большинство браузеров технически разрешат отправить такие запросы
  • многие серверные фреймворки не принимают данные форм с такими методами "из коробки"
  • старые браузеры и промежуточные прокси могут вести себя нестандартно

Поэтому распространен подход:

  • использовать method="post"
  • указывать "настоящий" метод в скрытом поле, например:
<form action="/users/1" method="post">
  <!-- Скрытое поле для указания "логического" метода -->
  <input type="hidden" name="_method" value="put" />
  <!-- Поля формы для редактирования -->
  <input name="name" />
  <button type="submit">Сохранить</button>
</form>

А на сервере:

  • читать поле _method
  • трактовать запрос как PUT, DELETE и т.п.

Этот прием часто используется в фреймворках вроде Laravel, Ruby on Rails, некоторых Node.js-фреймворках.

Взаимодействие method с другими атрибутами формы

method и action

Атрибут action задает URL, на который отправляется форма. Атрибут method – HTTP-метод.

Пример комбинации:

<form action="/api/users" method="post">
  <!-- Поле для имени -->
  <input type="text" name="name" />
  <!-- Поле для email -->
  <input type="email" name="email" />
  <!-- Кнопка отправки -->
  <button type="submit">Создать пользователя</button>
</form>

Комментарии:

  • если action не указан, форма отправляется на текущий URL страницы
  • если method не указан, используется GET

method и enctype

Атрибут enctype задает формат кодирования тела запроса. Он имеет смысл только для method="post" (и других методов с телом запроса).

Основные значения:

  1. application/x-www-form-urlencoded (по умолчанию)

    • поля формы кодируются в формате key=value&key2=value2
    • используются для обычных форм без файлов
  2. multipart/form-data

    • используется для отправки файлов
    • каждое поле и файл передаются как отдельная "часть" (boundary)
    • обязателен при type="file"
  3. text/plain

    • редко используется
    • данных кодируются "как есть" в текстовом виде
    • почти всегда лучше оставить application/x-www-form-urlencoded

Пример с enctype:

<form action="/profile" method="post" enctype="multipart/form-data">
  <!-- Имя пользователя -->
  <input type="text" name="name" />
  <!-- Аватар -->
  <input type="file" name="avatar" />
  <!-- Кнопка сохранения -->
  <button type="submit">Сохранить</button>
</form>

Комментарии:

  • если вы попытаетесь отправить файл без multipart/form-data – сервер его не получит корректно
  • для GET атрибут enctype игнорируется

method и атрибут formmethod у кнопок

Иногда нужно, чтобы одна и та же форма отправлялась разными методами в зависимости от кнопки. Для этого HTML предоставляет атрибут formmethod на элементах:

  • <button>
  • <input type="submit">

Смотрите, я покажу вам пример:

<form action="/items" method="post">
  <!-- Поле для названия товара -->
  <input type="text" name="title" />

  <!-- Кнопка отправки с методом POST (как у формы) -->
  <button type="submit">Сохранить (POST)</button>

  <!-- Кнопка отправки с методом GET -->
  <button type="submit" formmethod="get">Предпросмотр (GET)</button>
</form>

Как это работает:

  • первая кнопка использует метод, указанный в форме – POST
  • вторая кнопка переопределяет метод на GET только для этого нажатия

Комментарии:

  • formmethod всегда имеет приоритет над method формы
  • это удобно для "предпросмотра", "поиска" или вспомогательных действий

Как браузер кодирует данные формы в зависимости от method

GET и кодирование query string

Когда вы отправляете форму с method="get":

  1. Браузер берет все элементы с атрибутом name и подходящими типами
  2. Формирует пары имя–значение
  3. Применяет URL-кодирование:
    • пробелы, спецсимволы кодируются в %XX
  4. Склеивает пары через &
  5. Добавляет результат к URL после ?

Пример:

  • поля:

    • name = Иван
    • city = Москва
  • результат в URL (в виде, близком к реальному):

    /search?name=%D0%98%D0%B2%D0%B0%D0%BD&city=%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0

POST и кодирование тела запроса

Здесь многое зависит от enctype. Давайте разберем два основных случая.

application/x-www-form-urlencoded

Алгоритм почти такой же, как при GET, только результат помещается в тело запроса:

POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=admin&password=secret

Комментарии:

  • это формат по умолчанию
  • большинство серверных фреймворков "из коробки" умеют его разбирать

multipart/form-data

Этот формат сложнее. Структура тела запроса примерно такая:

POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryabc123

------WebKitFormBoundaryabc123
Content-Disposition: form-data; name="title"

Мой файл
------WebKitFormBoundaryabc123
Content-Disposition: form-data; name="file"; filename="photo.jpg"
Content-Type: image/jpeg

...здесь бинарное содержимое файла...
------WebKitFormBoundaryabc123--

Комментарии:

  • каждая часть отделяется строкой с boundary
  • поля формы и файлы становятся отдельными "секциями"
  • такой формат нужен именно для файлов и сложных структур

Рекомендации по выбору значения method

Базовые правила выбора

Давайте сформулируем простую схему:

  1. Если запрос читающий (получение данных, поиск, фильтр) – GET
  2. Если запрос изменяет данные (создание, обновление, удаление) – POST
  3. Если есть чувствительные данныеPOST + HTTPS
  4. Если есть файлыPOST + enctype="multipart/form-data"
  5. Если нужна ссылка, которой можно поделитьсяGET

Типичные примеры из практики

  • Форма поиска по сайту – GET
  • Фильтр каталога товаров – GET
  • Вход в аккаунт – POST
  • Регистрация – POST
  • Оформление заказа – POST
  • Обновление настроек профиля – POST
  • Предпросмотр контента (без сохранения) – чаще всего GET, иногда POST (если данные слишком большие)

Частые ошибки при использовании method

Давайте посмотрим на распространенные ситуации.

1. Использование GET для формы входа

<!-- Так делать не нужно -->
<form action="/login" method="get">
  <input type="text" name="username" />
  <input type="password" name="password" />
  <button type="submit">Войти</button>
</form>

Проблема:

  • пароль окажется в URL
  • он попадет в историю, логи, может утечь в реферере

Как исправить:

<form action="/login" method="post">
  <!-- Логин -->
  <input type="text" name="username" />
  <!-- Пароль -->
  <input type="password" name="password" />
  <!-- Кнопка входа -->
  <button type="submit">Войти</button>
</form>

И обязательно использовать HTTPS на стороне сервера.

2. Отправка больших текстов через GET

<!-- Так делать не стоит -->
<form action="/preview" method="get">
  <!-- Большое текстовое поле -->
  <textarea name="content"></textarea>
  <button type="submit">Предпросмотр</button>
</form>

Проблема:

  • контент может не поместиться в URL
  • возникнут ошибки "URI too long"

Лучше:

<form action="/preview" method="post">
  <!-- Большой текст отправляем через POST -->
  <textarea name="content"></textarea>
  <button type="submit">Предпросмотр</button>
</form>

3. Игнорирование семантики HTTP

Иногда разработчики используют POST всегда, "на всякий случай". Это:

  • ломает кэширование
  • делает ссылки на поисковые запросы неудобными
  • ухудшает совместимость с некоторыми клиентами

Поддерживайте различие между:

  • безопасными, идемпотентными операциями (GET)
  • изменяющими состояние операциями (POST)

Взаимодействие с JavaScript и AJAX

Хотя атрибут method относится к HTML-формам, он часто используется совместно с JavaScript.

Использование method при отправке через fetch

Даже если вы отправляете форму через JavaScript, имеет смысл:

  • читать method из формы
  • использовать его в запросе

Пример:

<form id="userForm" action="/api/users" method="post">
  <!-- Поле для имени -->
  <input type="text" name="name" />
  <!-- Поле для email -->
  <input type="email" name="email" />
  <!-- Кнопка отправки -->
  <button type="submit">Сохранить</button>
</form>

<script>
// Находим форму
const form = document.getElementById('userForm');

form.addEventListener('submit', async (event) => {
  // Отменяем стандартную отправку
  event.preventDefault();

  // Берем URL и метод из атрибутов формы
  const url = form.action; // /api/users
  const method = form.method; // post

  // Собираем данные формы
  const formData = new FormData(form); // Собирает все поля name=value

  // Отправляем запрос с тем же методом, что у формы
  const response = await fetch(url, {
    method: method, // Используем значение из атрибута method
    body: formData  // Отправляем данные формы
  });

  // Обрабатываем ответ
  const result = await response.json();
  // Здесь можно обновить интерфейс
});
</script>

Здесь вы видите, как метод формы определяет HTTP-метод запроса даже при кастомной отправке.

Проверка и изменение method через JavaScript

Иногда нужно динамически менять метод отправки. Это не всегда хорошая идея, но технически возможно.

Пример:

// Находим форму
const form = document.querySelector('form');

// Меняем метод на POST в зависимости от условия
if (shouldUsePost()) {
  form.method = 'post'; // Меняем атрибут method у формы
}

Комментарии:

  • form.method – свойство DOM-объекта, которое синхронизируется с атрибутом в HTML
  • такое изменение влияет на дальнейшую отправку формы

Заключение

Атрибут method в HTML определяет способ отправки данных формы и напрямую влияет на:

  • безопасность (видны ли данные в URL)
  • объем передаваемой информации
  • кэширование и работу истории браузера
  • семантику HTTP и обработку запросов на сервере

Основные практические выводы:

  • используйте GET для чтения данных, поиска и фильтров
  • используйте POST для изменения данных, регистрации, авторизации и любых чувствительных операций
  • передавайте файлы только через POST в сочетании с multipart/form-data
  • избегайте передачи паролей и персональных данных через GET
  • корректно используйте formmethod у кнопок, если нужно временно переопределять метод

Если вы будете осознанно выбирать значение method, ваши формы станут:

  • безопаснее
  • предсказуемее в поведении
  • проще в поддержке на стороне сервера

Частозадаваемые технические вопросы по теме атрибута method в HTML

Можно ли отправить JSON из обычной HTML-формы с методом POST

Да, но стандартная форма не умеет сама создавать JSON. Обычно делают так

  1. Вешаете обработчик submit на форму
  2. Собираете данные в объект
  3. Сериализуете в JSON и отправляете через fetch с Content-Type: application/json
    Стандартная отправка формы (без JS) всегда кодирует данные как application/x-www-form-urlencoded или multipart/form-data.

Почему сервер не видит данные при методе POST хотя форма отправляется

Частая причина – отсутствие корректного парсера тела запроса на сервере. Проверьте

  1. Установлен ли парсер urlencoded или multipart (в зависимости от enctype)
  2. Совпадает ли ожидаемый метод маршрута на сервере (например, app.post(...)) с method формы
  3. Не превышен ли лимит размера тела запроса в настройках сервера.

Можно ли использовать method="put" или method="delete" без JavaScript

Технически да – браузер отправит такой запрос. Но

  1. Многие серверы и фреймворки по умолчанию не принимают формы с этими методами
  2. Промежуточные прокси могут вести себя нестандартно
    На практике чаще используют POST плюс скрытое поле _method, а "настоящий" метод эмулируют на сервере.

Как запретить браузеру повторно отправлять POST при обновлении страницы

Полностью запретить нельзя – это стандартное поведение. Рекомендуемый подход – шаблон Post Redirect Get

  1. Принимаете POST на сервере
  2. Обрабатываете данные
  3. Возвращаете ответ с перенаправлением (status 302/303) на страницу результата
  4. Пользователь видит результат по GET и обновление страницы не вызывает повторный POST.

Почему при методе GET нажатие Back в браузере сразу показывает старые результаты

Браузер кэширует результат GET-запроса и часто восстанавливает страницу из истории без нового запроса. Если это нежелательно

  1. Настройте HTTP-заголовки Cache-Control и Pragma на стороне сервера
  2. При необходимости добавляйте в URL временные метки или другие параметры, чтобы делать запросы уникальными и контролировать кэширование.
Стрелочка влевоОпция списка HTML option - как работает и как правильно использоватьЗаголовок группы HTML legend - как правильно использовать и оформлятьСтрелочка вправо

Постройте личный план изучения Html до уровня Middle — бесплатно!

Html — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Все гайды по Html

Тег nav в HTML - полное руководство по семантической навигацииТег section в HTML - семантическая разметка структуры страницыТег main в HTML - подробное руководство по использованиюТег header в HTML - полное практическое руководствоТег footer в HTML - назначение семантика и практические примерыТег figure в HTML - как правильно оформлять иллюстрации и подписиТег figcaption в HTML - подробное руководство с примерамиТег aside в HTML - назначение правильная семантика и примеры
Текстовая область HTML textarea - практическое руководствоВыпадающий список HTML select - полное руководство для разработчиковОпция списка HTML option - как работает и как правильно использоватьАтрибут method в HTML - как правильно отправлять данные формыЗаголовок группы HTML legend - как правильно использовать и оформлятьТег input в HTML - типы атрибуты валидация и примерыТег формы form в HTMLГруппа полей HTML fieldsetАтрибут action в HTML - как правильно задавать адрес отправки формы
Открыть базу знаний

Лучшие курсы по теме

изображение курса

HTML и CSS

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий