Menu
CoddyTech

Страница, вызывающая API

Часть раздела REST API путешествия по Node.js на Coddy. Урок 21 из 25.

Страница вызывает ваш API с помощью fetch. Для POST нужны три параметра: метод, заголовки и тело. Преобразуйте объект JavaScript в текст JSON для тела и укажите для этого текста тип application/json.

const response = await fetch('/api/books', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({title: title}),
});
const data = await response.json();

Первый await получает HTTP-ответ. Второй считывает его тело JSON. response.ok сообщает, находится ли его статус в диапазоне успешных. Статус, например 400 или 409, не отклоняет промис fetch; он возвращает ответ, у которого ok имеет значение false. Код формы и списка предоставлен; сосредоточьтесь на отправке запроса и обработке результата.

Предоставленная переменная message указывает на абзац сообщения на странице. Присвойте её textContent отображаемый текст или пустую строку, чтобы очистить его:

message.textContent = data.error.message;
// Очистить после успешного выполнения:
message.textContent = '';

Страница и API имеют общий источник, поэтому этому вызову не требуется разрешение CORS. FormData кодирует форму иначе, чем JSON; используйте текст JSON, поскольку этот API использует express.json().

challenge icon

Задание

Легко

У вашего API пока нет интерфейса. Создайте для него небольшую страницу, которую будет обслуживать тот же сервер и форма которой добавляет задачи через API.

  1. В server.js обслуживайте папку public с помощью express.static, чтобы GET / возвращал public/index.html.
  2. В public/index.html обработчик отправки формы уже считывает заголовок задачи. Настройте отправку новой задачи в API:
    • Используйте предоставленную переменную title, содержащую текст из поля ввода.
    • Отправьте её методом POST с помощью fetch('/api/tasks', ...).
    • Тело запроса — это текст в формате JSON, созданный с помощью JSON.stringify, например {"title":"Water the plants"}.
    • В запросе необходим заголовок 'Content-Type': 'application/json' в параметре headers вызова fetch, иначе express.json() не прочитает тело запроса.
  3. Если ответ успешный (его свойство ok равно true для любого статуса от 200 до 299), очистите форму с помощью form.reset(), очистите #message и вызовите load(), чтобы список отобразил новую задачу.
  4. В противном случае тело ответа содержит описанную ранее структуру ошибки, например:
    { "error": { "code": "conflict", "message": "A task with this title already exists" } }
    Выведите её message в абзаце #message.

Проверки запускают предоставленный скрипт страницы с небольшой имитацией формы и настоящим API урока. Они отправляют задачу и её дубликат, а затем проверяют список, форму и сообщение. Также попробуйте открыть настоящую страницу рядом с редактором.

Попробуйте: отправьте GET /. Страница откроется в окне просмотра страницы с 3 начальными задачами. Введите "Water the plants" и нажмите «Добавить»: поле ввода очистится, а задача появится внизу списка. Снова введите "Water the plants" и нажмите «Добавить»: список останется без изменений, а под формой появится сообщение "A task with this title already exists".

Попробуйте сами

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Tasks</title>
</head>
<body>
    <h1>Tasks</h1>
    <ul id="list"></ul>
    <form id="add">
        <input name="title" placeholder="New task" required>
        <button>Add</button>
    </form>
    <p id="message"></p>
    <script>
        const list = document.querySelector('#list');
        const form = document.querySelector('#add');
        const message = document.querySelector('#message');

        async function load() {
            const response = await fetch('/api/tasks?limit=50');
            const page = await response.json();
            list.replaceChildren(...page.items.map((task) => {
                const item = document.createElement('li');
                item.textContent = (task.done ? '[x] ' : '[ ] ') + task.title;
                return item;
            }));
        }

        form.addEventListener('submit', async (event) => {
            event.preventDefault();
            const title = form.elements.title.value;
            // Send the title to POST /api/tasks as JSON. On success clear
            // the form and load() again; on an error show its message.
        });

        load();
    </script>
</body>
</html>

Все уроки раздела REST API

Потренируйтесь самостоятельно: Песочница Express