Поиск публикаций
Работа с HTTP
Содержание
Синхронный GET
http.получитьСинх(адрес, параметры)
Выполняет синхронный GET-запрос по указанному адресу. Блокирует выполнение скрипта до получения ответа. Параметры запроса передаются в виде объекта.
₽ответ = http.получитьСинх("http://httpbin.org/get", {}); лог("Статус: " + строка(₽ответ.статус));
Синхронный POST (с JSON)
http.отправитьСинх(адрес, данные, параметры)
Выполняет синхронный POST-запрос с передачей данных. Обычно используется для отправки JSON или формы.
₽данные = {"name": "WDSP", "version": 1.0}; ₽ответ = http.отправитьСинх("http://httpbin.org/post", ₽данные, {"contentType": "application/json"});
Асинхронный GET
http.получить(адрес, параметры, колбэк)
Выполняет асинхронный GET-запрос. Ответ обрабатывается в переданной функции-колбэке. Не блокирует выполнение скрипта.
http.получить("http://httpbin.org/get", {}, функция(₽ответ) { лог("Ответ получен"); } );
Асинхронный POST (JSON)
http.отправитьJSON(адрес, данные, параметры, колбэк)
Упрощённая функция для отправки JSON-данных методом POST. Автоматически устанавливает заголовок Content-Type: application/json.
http.отправитьJSON("http://httpbin.org/post", {"ключ": "значение"}, {}, функция(₽ответ) { лог("Ответ: " + ₽ответ.тело); } );
Асинхронный запрос с прогрессом и отменой
http.получитьСПрогрессом(адрес, параметры, колбэкПрогресса, колбэкЗавершения)
Выполняет асинхронный GET-запрос с отслеживанием прогресса загрузки. Возвращает объект-дескриптор, позволяющий отменить запрос методом .отмена().
отмена() для отмены запроса.статус может быть равно 0 или содержать сообщение об ошибке.₽прогрессHandle = http.получитьСПрогрессом( "http://example.com/largefile.zip", {}, функция(₽прогресс) { лог("Загружено: " + строка(₽прогресс.полученоБайт)); }, функция(₽ответ) { лог("Загрузка завершена"); } ); ... ₽прогрессHandle.отмена(); // отменить запрос
PUT (синхронный)
http.заменитьСинх(адрес, данные, параметры)
Выполняет синхронный PUT-запрос (обычно используется для замены ресурса). Аналогичен POST, но метод PUT.
₽ответ = http.заменитьСинх("http://httpbin.org/put", {"обновлено": истина}, {"contentType": "application/json"});
DELETE (синхронный)
http.удалитьСинх(адрес, параметры)
Выполняет синхронный DELETE-запрос для удаления ресурса.
₽ответ = http.удалитьСинх("http://httpbin.org/delete", {});
Установка таймаута
http.таймаут(миллисекунды)
Устанавливает глобальный таймаут для всех последующих запросов (в миллисекундах). Если запрос не завершается за указанное время, он прерывается с ошибкой.
таймаут. По умолчанию таймаут обычно составляет 30 секунд.http.таймаут(1000); // устанавливаем таймаут 1 секунду ₽ответ = http.получитьСинх("http://httpbin.org/delay/3", {}); // Запрос будет прерван по таймауту
Объект ответа
Все функции, возвращающие ответ, или колбэки, принимают объект со следующими полями:
статус— число (HTTP-статус, например 200, 404). В случае ошибки может быть 0.тело— строка (тело ответа).заголовки— объект с заголовками ответа (доступны по имени, например,₽ответ.заголовки["content-type"]).сообщениеОбОшибке— строка (текст ошибки, если запрос не удался).
Для запросов с прогрессом объект прогресса содержит поля:
полученоБайт— число (сколько байт уже получено).всегоПолучить— число (общий размер загрузки, если известен; иначе 0).
Обработка ошибок
При выполнении запроса могут возникать ошибки: недоступный хост, таймаут, сетевые проблемы. В синхронных функциях ошибка выбрасывается как исключение (её можно перехватить ловушка) или возвращается в объекте ответа с полем сообщениеОбОшибке. В асинхронных функциях ошибка передаётся в колбэк, где статус будет 0 и заполнено поле сообщениеОбОшибке.
попытка { ₽ответ = http.получитьСинх("http://nonexistent.domain", {}); } ловушка (₽ошибка) { лог("Ошибка: " + строка(₽ошибка)); }
Полный тестовый скрипт
Ниже приведён полный тест модуля «http», демонстрирующий все описанные функции с замерами времени.
/ ============================================================
// Полный тест модуля http (синхронные и асинхронные методы) с замерами времени
// ============================================================
// Вспомогательная функция для вывода с меткой
функция лог(₽сообщение) {
вывод("[HTTP Тест] " + строка(₽сообщение) + "\n");
}
// Запоминаем общее время начала теста
₽общееВремяНачала = время();
лог("=== 1. Синхронные GET и POST ===");
// 1.1 Синхронный GET
₽getВремяНачала = время();
₽getResp = http.получитьСинх("http://httpbin.org/get", {});
₽getВремяОкончания = время();
₽getДлительность = ₽getВремяОкончания - ₽getВремяНачала;
лог("GET синхронный, статус: " + строка(₽getResp.статус) + ", время: " + строка(округлить(₽getДлительность, 3)) + " с");
если (₽getResp.статус == 200) {
попытка {
₽json = парситьJSON(₽getResp.тело);
лог(" URL: " + ₽json.url);
} ловушка (₽e) {
лог(" Ошибка парсинга JSON: " + строка(₽e));
}
} иначе {
лог(" Ошибка: " + ₽getResp.сообщениеОбОшибке);
}
// 1.2 Синхронный POST с JSON
₽postData = {"name": "WDSP", "version": 1.0};
₽postВремяНачала = время();
₽postResp = http.отправитьСинх("http://httpbin.org/post", ₽postData, {"contentType": "application/json"});
₽postВремяОкончания = время();
₽postДлительность = ₽postВремяОкончания - ₽postВремяНачала;
лог("POST синхронный, статус: " + строка(₽postResp.статус) + ", время: " + строка(округлить(₽postДлительность, 3)) + " с");
если (₽postResp.статус == 200) {
попытка {
₽json = парситьJSON(₽postResp.тело);
лог(" Отправленные данные: " + строка(₽json.json));
} ловушка (₽e) {
лог(" Ошибка парсинга JSON: " + строка(₽e));
}
} иначе {
лог(" Ошибка: " + ₽postResp.сообщениеОбОшибке);
}
лог("=== 2. Асинхронные GET и POST (с колбэками) ===");
// 2.1 Асинхронный GET
₽asyncGetСтарт = время();
http.получить("http://httpbin.org/get", {},
функция(₽ответ) {
₽длит = время() - ₽asyncGetСтарт;
лог("GET асинхронный, статус: " + строка(₽ответ.статус) + ", время: " + строка(округлить(₽длит, 3)) + " с");
если (₽ответ.статус == 200) {
попытка {
₽json = парситьJSON(₽ответ.тело);
лог(" URL: " + ₽json.url);
} ловушка (₽e) {
лог(" Ошибка парсинга JSON: " + строка(₽e));
}
} иначе {
лог(" Ошибка: " + ₽ответ.сообщениеОбОшибке);
}
}
);
// 2.2 Асинхронный POST с JSON
₽asyncPostСтарт = время();
http.отправитьJSON("http://httpbin.org/post", {"ключ": "значение"}, {},
функция(₽ответ) {
₽длит = время() - ₽asyncPostСтарт;
лог("POST JSON асинхронный, статус: " + строка(₽ответ.статус) + ", время: " + строка(округлить(₽длит, 3)) + " с");
если (₽ответ.статус == 200) {
попытка {
₽json = парситьJSON(₽ответ.тело);
лог(" Прислано эхо: " + строка(₽json.json));
} ловушка (₽e) {
лог(" Ошибка парсинга JSON: " + строка(₽e));
}
} иначе {
лог(" Ошибка: " + ₽ответ.сообщениеОбОшибке);
}
}
);
пауза(2000);
лог("=== 3. Асинхронный GET с прогрессом и отменой ===");
₽прогрессUrl = "http://ipv4.download.thinkbroadband.com/10MB.zip";
₽progressСтарт = время();
₽progressHandle = http.получитьСПрогрессом(₽прогрессUrl, {},
функция(₽прогресс) {
если (₽прогресс.всегоПолучить > 0) {
₽процент = (₽прогресс.полученоБайт / ₽прогресс.всегоПолучить) * 100;
лог(" Прогресс: " + строка(округлить(₽процент, 1)) + "% (" + строка(₽прогресс.полученоБайт) + " / " + строка(₽прогресс.всегоПолучить) + " байт)");
} иначе {
лог(" Начало загрузки...");
}
},
функция(₽ответ) {
₽длит = время() - ₽progressСтарт;
лог("Загрузка завершена, статус: " + строка(₽ответ.статус) + ", время: " + строка(округлить(₽длит, 3)) + " с");
если (₽ответ.статус == 200) {
лог(" Размер полученных данных: " + строка(длина(₽ответ.тело)) + " байт");
} иначе {
лог(" Ошибка: " + ₽ответ.сообщениеОбОшибке);
}
}
);
// Увеличиваем паузу с 2 до 5 секунд, чтобы успеть увидеть прогресс
пауза(5000);
₽progressHandle.отмена();
лог(" Отмена запроса выполнена");
пауза(500);
лог("=== 4. Тестирование ошибок (недоступный хост) ===");
₽errorСтарт = время();
₽badResp = http.получитьСинх("http://nonexistent.domain.local/get", {});
₽errorДлит = время() - ₽errorСтарт;
лог("Недоступный хост (синхронный): статус = " + строка(₽badResp.статус) + ", ошибка = " + ₽badResp.сообщениеОбОшибке + ", время: " + строка(округлить(₽errorДлит, 3)) + " с");
₽asyncErrorСтарт = время();
http.получить("http://nonexistent.domain.local/get", {},
функция(₽ответ) {
₽длит = время() - ₽asyncErrorСтарт;
лог("Асинхронный недоступный хост: статус = " + строка(₽ответ.статус) + ", сообщение = " + ₽ответ.сообщениеОбОшибке + ", время: " + строка(округлить(₽длит, 3)) + " с");
}
);
пауза(1000);
лог("=== 5. PUT и DELETE (синхронно) ===");
₽putСтарт = время();
₽putResp = http.заменитьСинх("http://httpbin.org/put", {"обновлено": истина}, {"contentType": "application/json"});
₽putДлит = время() - ₽putСтарт;
лог("PUT синхронный, статус: " + строка(₽putResp.статус) + ", время: " + строка(округлить(₽putДлит, 3)) + " с");
если (₽putResp.статус == 200) {
попытка {
₽json = парситьJSON(₽putResp.тело);
лог(" PUT ответ: " + строка(₽json.json));
} ловушка (₽e) {
лог(" Ошибка парсинга JSON: " + строка(₽e));
}
}
₽delСтарт = время();
₽delResp = http.удалитьСинх("http://httpbin.org/delete", {});
₽delДлит = время() - ₽delСтарт;
лог("DELETE синхронный, статус: " + строка(₽delResp.статус) + ", время: " + строка(округлить(₽delДлит, 3)) + " с");
если (₽delResp.статус == 200) {
попытка {
₽json = парситьJSON(₽delResp.тело);
лог(" DELETE подтверждён: " + строка(₽json.url));
} ловушка (₽e) {
лог(" Ошибка парсинга JSON: " + строка(₽e));
}
}
лог("=== 6. Тестирование таймаута ===");
http.таймаут(1000);
₽timeoutСтарт = время();
₽slowResp = http.получитьСинх("http://httpbin.org/delay/3", {});
₽timeoutДлит = время() - ₽timeoutСтарт;
лог("Запрос с таймаутом 1с (задержка 3с): статус = " + строка(₽slowResp.статус) + ", ошибка = " + ₽slowResp.сообщениеОбОшибке + ", время: " + строка(округлить(₽timeoutДлит, 3)) + " с");
http.таймаут(30000);
// Общее время теста
₽общаяДлительность = время() - ₽общееВремяНачала;
лог("=== Тестирование завершено, общее время выполнения: " + строка(округлить(₽общаяДлительность, 3)) + " с ===");