Была ли статья полезной?
- Введение [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
- Работа с типами
- Глобальный контекст и изоляция
- Работа с приложениями
- Массовые действия с элементами приложения
- Работа с внешними сервисами
- Скрипты в виджетах
- Веб компоненты
- Права доступа
- Начало работы с процессами
- Начало работы с подписями
- Начало работы с предпросмотром файлов
- Начало работы с организационной структурой
- Начало работы с пользователями и группами
- Начало работы с типом данных Таблица
- Начало работы с типом данных Категория
- Динамическое вычисление типа события
- Решение типовых задач
- API
В этой статье
Работа с внешними сервисами
Для интеграций со сторонними сервисами в скриптах доступна глобальная функция fetch. Функция использует нативный Fetch API в браузере и библиотеку-полифил на сервере, поэтому её интерфейс в нашем SDK совмещает доступные для них возможности.
Сервер On-Premises может находиться за прокси-сервером. В этом случае для работы с внешними сервисами необходимо указать параметры прокси-сервера в переменных окружения
HTTP_PROXYиHTTPS_PROXYсервера системы.О том, как это сделать, читайте в статье «Установка ELMA365 в MicroK8s с proxy-сервером».
Пример использования функции
fetch():const res = await fetch('https://my.server/api/products', { method: 'POST', headers: { Authorization: 'Bearer SOME-TOKEN-HERE', }, body: JSON.stringify({ name: 'New product', cost: 13.20, }) }); if (!res.ok) { // Обработка ошибки с кодом ответа >=300 } const product = await res.json();Простой GET-запрос можно выполнить без передачи дополнительных параметров:
const res = await fetch(`https://my.server/api/products/${ Context.data.itemId }`);В параметрах запроса можно передать метод FetchRequest.method, заголовки запроса FetchRequest.headers в виде обычного объекта Record<string, string> и тело запроса FetchRequest.body в виде строки.
Подробнее о fetch()
JavaScript может отправлять сетевые запросы на сервер и подгружать новую информацию по мере необходимости.
Например, мы можем использовать сетевой запрос, чтобы:
Для сетевых запросов из JavaScript есть широко известный термин "AJAX" (аббревиатура от Asynchronous JavaScript And XML). XML мы использовать не обязаны, просто термин старый, поэтому в нём есть это слово. Возможно, вы его уже где-то слышали.
Есть несколько способов делать сетевые запросы и получать информацию с сервера.
Метод
fetch()— современный и очень мощный, поэтому начнём с него.Базовый синтаксис:
let promise = fetch(url, options)url— URL для отправки запроса.options— дополнительные параметры: метод, заголовки и так далее.Без
optionsэто простой GET-запрос, скачивающий содержимое по адресуurl.Браузер сразу же начинает запрос и возвращает промис, который внешний код использует для получения результата.
Процесс получения ответа обычно происходит в два этапа.
Во-первых,
promiseвыполняется с объектом встроенного класса Response в качестве результата, как только сервер пришлёт заголовки ответа.На этом этапе мы можем проверить статус HTTP-запроса и определить, выполнился ли он успешно, а также посмотреть заголовки, но пока без тела ответа.
Промис завершается с ошибкой, если
fetchне смог выполнить HTTP-запрос, например при ошибке сети или если нет такого сайта. HTTP-статусы 404 и 500 не являются ошибкой.Мы можем увидеть HTTP-статус в свойствах ответа:
status— код статуса HTTP-запроса, например 200.ok— логическое значение: будетtrue, если код HTTP-статуса в диапазоне 200-299.Например:
let response = await fetch(url); if (response.ok) { // если HTTP-статус в диапазоне 200-299 // получаем тело ответа (см. про этот метод ниже) let json = await response.json(); } else { alert("Ошибка HTTP: " + response.status); }Во-вторых, для получения тела ответа нам нужно использовать дополнительный вызов метода.
Responseпредоставляет несколько методов, основанных на промисах, для доступа к телу ответа в различных форматах:response.text()— читает ответ и возвращает как обычный текст,response.json()— декодирует ответ в формате JSON,response.arrayBuffer()— возвращает ответ какArrayBuffer(низкоуровневое представление бинарных данных),Например, получим JSON-объект с последними коммитами из репозитория на GitHub:
let url = 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits'; let response = await fetch(url); let commits = await response.json(); // читаем ответ в формате JSON alert(commits[0].author.login);То же самое без
await, с использованием промисов:fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits') .then(response => response.json()) .then(commits => alert(commits[0].author.login));Для получения ответа в виде текста используем
await response.text()вместо.json():let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits'); let text = await response.text(); // прочитать тело ответа как текст alert(text.slice(0, 80) + '...');Внимание! Мы можем выбрать только один метод чтения ответа.
Если мы уже получили ответ с
response.text(), тогдаresponse.json()не сработает, так как данные уже были обработаны.let text = await response.text(); // тело ответа обработано let parsed = await response.json(); // ошибка (данные уже были обработаны)Заголовки ответа
Заголовки ответа хранятся в похожем на
Mapобъектеresponse.headers.Это не совсем
Map, но мы можем использовать такие же методы, как сMap, чтобы получить заголовок по его имени или перебрать заголовки в цикле:let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits'); // получить один заголовок alert(response.headers.get('Content-Type')); // application/json; charset=utf-8 // перебрать все заголовки for (let [key, value] of response.headers) { alert(`${key} = ${value}`); }Заголовки запроса
Для установки заголовка запроса в
fetchмы можем использовать опциюheaders. Она содержит объект с исходящими заголовками, например:let response = fetch(protectedUrl, { headers: { Authentication: 'secret' } });Есть список запрещённых HTTP-заголовков, которые мы не можем установить:
Accept-Charset,Accept-EncodingAccess-Control-Request-HeadersAccess-Control-Request-MethodConnectionContent-LengthCookie,Cookie2DateDNTExpectHostKeep-AliveOriginRefererTETrailerTransfer-EncodingUpgradeViaProxy-*Sec-*Эти заголовки обеспечивают достоверность данных и корректную работу протокола HTTP, поэтому они контролируются исключительно браузером.
POST-запросы
Для отправки
POST-запроса или запроса с другим методом, нам необходимо использоватьfetchпараметры:method— HTTP метод, напримерPOST,body— тело запроса, одно из списка:FormDataдля отправки данных какmultipart/form-data.Чаще всего используется строка в формате JSON.
Например, этот код отправляет объект
userкак JSON:let user = { name: 'John', surname: 'Smith' }; let response = await fetch('/article/fetch/post/user', { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify(user) }); let result = await response.json(); alert(result.message);Заметим, что так как тело запроса
body- строка, то заголовокContent-Typeпо умолчанию будетtext/plain;charset=UTF-8.Но, так как мы посылаем JSON, то используем параметр
headersдля отправки вместо этогоapplication/json, правильныйContent-Typeдля JSON.Отправка файла
Мы можем отправить бинарные данные при помощи
fetch, используя объектыFormDataиArrayBuffer.async function submit() { let data_req = await fetch('/external/data/to/load'); let buffer = await data_req.arrayBuffer(); let form = new FormData(); form.append('file', buffer, 'filename.ext'); let response = await fetch('/article/fetch/post/file', { method: 'POST', body: form }); // сервер ответит подтверждением и размером изображения let result = await response.json(); alert(result.message); }Заметим, что здесь нам не нужно вручную устанавливать заголовок
Content-Type, потому что он автоматически установится вmultipart/form-data.Итого
Типичный запрос с помощью
fetchсостоит из двух операторовawait:let response = await fetch(url, options); // завершается с заголовками ответа let result = await response.json(); // читать тело ответа в формате JSONИли, без
await:fetch(url, options) .then(response => response.json()) .then(result => /* обрабатываем результат */)Параметры ответа:
response.status— HTTP-код ответа,response.ok—true, если статус ответа в диапазоне 200-299.response.headers— похожий наMapобъект с HTTP-заголовками.Методы для получения тела ответа:
response.text()— возвращает ответ как обычный текст,response.json()— преобразовывает ответ в JSON-объект,response.arrayBuffer()— возвращает ответ как ArrayBuffer (низкоуровневые бинарные данные).