- Главная [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
- Типы объектов
- Типы данных
- Глобальные константы
- Работа с приложениями
- Веб-запросы
- Права доступа
- Документооборот
- Линии
- Виджет «Код»
- Подписи
- Рабочие календари
- Интеграция с IP-телефонией
- Интеграция с сервисами рассылок
В этой статье
Работа с внешними сервисами
Для интеграций со сторонними сервисами в скриптах доступна глобальная функция 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-Encoding
Access-Control-Request-Headers
Access-Control-Request-Method
Connection
Content-Length
Cookie
,Cookie2
Date
DNT
Expect
Host
Keep-Alive
Origin
Referer
TE
Trailer
Transfer-Encoding
Upgrade
Via
Proxy-*
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 (низкоуровневые бинарные данные).