Mithril.js предоставляет встроенный модуль m.request,
который служит для выполнения асинхронных HTTP-запросов. Он сочетает в
себе простоту использования и гибкость настройки, позволяя работать с
REST API, GraphQL и любыми другими HTTP-сервисами.
m.requestФункция m.request принимает объект конфигурации, где
задаются следующие ключевые параметры:
method — HTTP-метод запроса (GET,
POST, PUT, DELETE и др.). По
умолчанию используется GET.url — адрес ресурса, к которому выполняется
запрос.body — данные запроса для методов, которые поддерживают
тело запроса (POST, PUT,
PATCH).params — объект с параметрами URL-запроса,
автоматически сериализуемыми в строку запроса.headers — объект с HTTP-заголовками, например
{ "Authorization": "Bearer TOKEN" }.responseType — тип ожидаемого ответа
(json, text, document и др.). По
умолчанию json.withCredentials — логическое значение для включения
передачи куки.timeout — максимальное время ожидания ответа в
миллисекундах.deserialize — функция для кастомной обработки данных
ответа.serialize — функция для кастомной сериализации тела
запроса.Пример базового GET-запроса с параметрами:
m.request({
method: "GET",
url: "/api/users",
params: { page: 2, limit: 20 },
headers: { "Authorization": "Bearer abc123" }
}).then(response => {
console.log(response);
});
Для упрощения многократных запросов можно использовать
глобальную конфигурацию через переопределение
m.request с функцией-обёрткой. Это позволяет
централизованно задавать заголовки, обработку ошибок и логику
сериализации.
Пример глобальной конфигурации с обработкой ошибок:
function apiRequest(options) {
return m.request({
...options,
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${localStorage.getItem('token')}`,
...(options.headers || {})
},
deserialize: data => JSON.parse(data),
}).catch(err => {
console.error("Ошибка API:", err);
throw err;
});
}
// Использование
apiRequest({ method: "GET", url: "/api/profile" })
.then(profile => console.log(profile));
Mithril-компоненты могут напрямую использовать промисы, возвращаемые
m.request, для динамического обновления интерфейса.
Ключевой момент — вызов m.redraw() не обязателен, так как
Mithril автоматически перерисовывает компоненты после разрешения
промиса.
Пример интеграции запроса в компонент:
const UserList = {
users: [],
oninit() {
m.request({ method: "GET", url: "/api/users" })
.then(data => { UserList.users = data; });
},
view() {
return m("ul",
UserList.users.map(user => m("li", user.name))
);
}
};
Для сложных API часто требуется изменять формат отправляемых данных
или обрабатывать нестандартные ответы. serialize и
deserialize предоставляют полный контроль:
m.request({
method: "POST",
url: "/api/upload",
body: { file: fileData },
serialize: body => {
const formData = new FormData();
formData.append("file", body.file);
return formData;
},
deserialize: response => response.status === "ok"
})
.then(result => console.log(result));
Mithril поддерживает отмену запросов через объект
AbortController, что особенно важно для предотвращения
гонок данных и утечек памяти при динамическом обновлении интерфейса:
const controller = new AbortController();
m.request({
method: "GET",
url: "/api/long-process",
signal: controller.signal
}).catch(err => {
if (err.name === "AbortError") console.log("Запрос отменён");
});
// Отмена запроса
controller.abort();
Таймаут задаётся в миллисекундах через опцию timeout.
Если сервер не отвечает в течение заданного времени, промис
отклоняется:
m.request({
method: "GET",
url: "/api/data",
timeout: 5000
}).catch(err => console.error("Таймаут запроса:", err));
Опция withCredentials позволяет отправлять куки вместе с
запросом. Это важно для авторизации через сессионные токены на
сервере:
m.request({
method: "GET",
url: "/api/private",
withCredentials: true
});
Для REST m.request удобно использовать с
params и body. Для GraphQL часто применяется
POST-запрос с JSON-телом:
m.request({
method: "POST",
url: "/graphql",
body: { query: "{ users { id, name } }" },
headers: { "Content-Type": "application/json" }
});
m.request по умолчанию отклоняет промис при статусах
HTTP 4xx и 5xx. Для кастомной обработки можно использовать
then и catch, а также проверять поле
status объекта ошибки:
m.request({ method: "GET", url: "/api/missing" })
.then(data => console.log("Данные:", data))
.catch(err => {
console.log("Статус:", err.code);
console.log("Сообщение:", err.message);
});
serialize/deserialize при работе с
нестандартными API.oninit или других жизненных циклах.AbortController для отмены долгих или
устаревших запросов.Эта конфигурация обеспечивает гибкость и надёжность работы с любыми HTTP-сервисами, интегрируя их напрямую в реактивную архитектуру Mithril.