Кроссдоменные HTTP-запросы к 1С

13.09.16

Разработка - Запросы

В чистом виде, так сказать, в естественной среде браузерного окружения, кроссдоменные запросы — штука не тривиальная. Но если сюда добавить 1С, то становится все совсем плохо.

Самое большое удобство в появлении http-сервисов, на мой взгляд, представляет возможность построения web-приложений, реализующих определенный функционал части конфигурации. Это могут быть какие угодно программы, от dashboard-ов до самостоятельных приложений. Практически любые ваши фантазии, подкрепленные возможностью организации rest архитектуры приложения.

В моем случае вопрос стал в разработке личного web-кабинета для системы управления проектами. Главная проблема была в том, что само web-приложение и http-сервис 1С располагаются на разных доменах. Хотя не обязательно все организовывать так сложно. Самый просто пример может выглядеть так: web-сервис от 1С на localhost и страничка html открытая как файл. Причем последняя может попробовать обратиться к сервисам 1С и получит, как это принято говорить, "болт".

ВНИМАНИЕ: Прежде чем вы продолжите читать, я сразу предупрежу: вам должно быть понятны такие вещи, как html, javacript. В противном случае, я предлагаю поставить эту статью в избранное и вернуться позже.

CORS наше все

Поддержка XMLHttpRequest с CORS есть не во всех браузерах. Но с учетом количества пользователей Safari 4+, Chrome 3+, IE 10+ вполне достаточно чтобы рассматривать данную технологию, как основную к использованию.

Пы.сы. я знаю что есть JSONP, но он позволяет только GET-запросы, к тому же имеет и другие ограничения. А проксирование через фреймы заставляет использовать сторонние библиотеки, либо писать жуткие велосипеды.

Начнем с небольшого куска кода (мне удобнее использовать синтаксис angular, но знающие jquery с легкостью прочитают этот код и перепишут).

$http.post('http://localhost/mybase/hs/inbox/user')
        .success(function(data){
            alert('success');
        })
        .error(function(data){
            alert('error');
        });

Данный запрос (при условии иного домена у инициатора) вызовет ошибки следующего характера:

XMLHttpRequest cannot load http://localhost/mybase/hs/inbox/user. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

Рассмотрим повнимательнее как сам запрос, так и ответ. И начнем с заголовков. С клиентской стороны все вроде как обычно, но добавлен заголовок с именем домена, откуда делается запрос: Origin: http://localhost:63342

При этом сервер нам вполне доходчиво объясняет что ему не хватает заголовка с определением области доступа (Access-Control-Allow-Origin). Если мы попробуем добавить этот заголовок с указанием "*" в наш ответ, то запрос будет выполнен.

Однако, в свой ответ я добавил еще несколько заголовков для более конкретного описания области доступа. 

	Ответ = Новый HTTPСервисОтвет(200);
	Ответ.Заголовки.Вставить("Access-Control-Allow-Origin", "http://localhost:63342");
	Ответ.Заголовки.Вставить("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, HEAD, OPTIONS");
	Ответ.Заголовки.Вставить("Access-Control-Allow-Credentials", "true");
	Ответ.Заголовки.Вставить("Access-Control-Allow-Headers", "X-Requested-With, origin, content-type, accept");

Такой способ применим, только если в качестве веб-сервера вы используете IIS. Для Apache необходимо делать несколько иначе. В файле httpd.config необходимо внести следующие изменения:

1. Найти строку "#LoadModule headers_module modules/mod_headers.so" и убрать первый символ "#"

2. В раздел "<Directory />" (также при наличии Location, Files) вписать следующее (соответственно указав области доступа более конкретно.):

<IfModule mod_headers.c>
   Header always set Access-Control-Allow-Origin "*"
   Header always set Access-Control-Max-Age "1000"
   Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding"
   Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
</IfModule>

Вот такое элегантное решение. Без лишних HTTP запросов, без изменения клиентского API.

От автора

Если у вас есть важные дополнения, замечания или критика, пишите, не стесняйтесь, пожалуйста. Все будет учтено, и статья будет дополнена.

ajax rest http-сервисы

См. также

SALE! %

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

12000 10000 руб.

02.09.2020    93321    476    380    

531

Нахождение уникальных наборов строк таблицы запросом

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Решение задачи нахождения уникальных наборов строк таблицы запросом

23.07.2023    4366    tormozit    78    

38

Структура запроса

Инструментарий разработчика Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Абонемент ($m)

Обработка использует схему запроса и строит визуальную структуру источников данных в виде дерева. Пригодится при разборе прежде всего чужих, громоздких запросов и позволит быстро получить список источников данных. Единственное ограничение - текст запроса должен соответствовать метаданным текущей конфигурации.

1 стартмани

21.06.2023    4267    50    obmailok    35    

53

MS SQL Server: изучаем планы запросов

Запросы HighLoad оптимизация Запросы Бесплатно (free)

Многие знают, что для ускорения работы запроса нужно «изучить план». При этом сам план обычно обескураживает: куча разноцветных иконок и стрелочек; ничего не понятно, но очень интересно! Аналитик производительности Александр Денисов на конференции Infostart Event 2021 Moscow Premiere рассказал, как выполняется план запроса и что нужно сделать, чтобы с его помощью находить проблемы производительности.

20.06.2023    7611    Филин    37    

92

Как собрать отладчиком отдельные части запроса в один

Запросы Платформа 1С v8.3 Запросы Россия Бесплатно (free)

Подробное описание функционала загрузки данных запроса из отладчика в консоли "Анализатор сложных запросов".

21.03.2023    3456    manuel    2    

19

Все консоли запросов для 1С

Запросы Бесплатно (free)

Список всех популярных обработок.

17.03.2023    19219    kuzyara    70    

147

Обработка результатов запроса произвольными вычисляемыми полями. Обзор некоторых новых функций СКД

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

В данной статье вспомним, как обрабатывать результаты запроса в вычисляемых полях СКД, а также сделаем небольшой обзор на новые функции СКД платформы 8.3.20.

07.02.2023    4729    quazare    7    

38

Идентификатор объекта в запросе. Вы этого хотели?

Запросы Механизмы платформы 1С Платформа 1С v8.3 Запросы Бесплатно (free)

В платформе 8.3.22 появилась возможность получать идентификатор в запросе. Лично я ждал этого давно, но по итогу ждал большего. Что не так?

12.01.2023    22366    dsdred    24    

82
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. vano-ekt 122 30.08.15 17:43 Сейчас в теме
м.б. пользователю службы апача сделать авторизацию ОС?
2. pahalovo 31.08.15 05:30 Сейчас в теме
Для IIS можно прописать в web.config (находится каталоге куда публикуется http сервис 1С)
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>

Все заголовки которые перечислены в customHeader будут автоматически добавляться к http-ответам.

Тоже разрабатываю личный кабинет к системе учета заявок на angular.js и http-сервисах 1С, и сейчас застрял на кросс доменной авторизации пользователей.
chessman; +1 Ответить
3. vandalsvq 1412 31.08.15 09:20 Сейчас в теме
(2) pahalovo, я намерено не указал данный метод, поскольку при обновлении публикации 1с меняет файл. А постоянно туда лазить не хочется. Более того, разрешение будет выдано на все сервисы, а это уже определенная брешь в безопасности. В аппаче же другого выхода нет кроме правки настроек веб-сервера. Ну или я что то не умею ))))
5. unpete 578 03.09.15 16:13 Сейчас в теме
(3)
при таком раскладе авторизация пользователя средствами платформы уже отпадает

1. Что мешает установить в XHR
withCredentials = true
и добавить заголовок
Authorization

2. На самом деле, заголовки
Access-Control...
нужны не всегда, а только при обработке запроса типа
OPTIONS
. Такой минизапрос браузер добавляет перед выполнением реального кроссдоменного запроса. Можно добавлять всегда - ничего страшного в отправке нескольких лишних байт нет.
vandalsvq; +1 Ответить
7. vandalsvq 1412 03.09.15 20:47 Сейчас в теме
(5) unpete, спасибо за подсказку относительно заголовка Auhorization. Чего-то я не подумал так попробовать. Впрочем в рамках моей задачи не требовалась авторизация под конкретными пользователями. Но в любом случае, спасибо.
8. unpete 578 03.09.15 21:35 Сейчас в теме
(7) На самом деле, CORS с авторизацией несколько сложнее, т.к. сервер должен в этом случае возвращать не "Access-Control-Allow-Origin: *", а "Access-Control-Allow-Origin: Origin инициатора"
imho, правильнее не преодолевать героически самостоятельно созданные проблемы, а выбирать архитектуру, в которой эти проблемы в принципе не возникнут.
У администратора веб-сервера, всегда есть возможность подклеить http://bad.cors.com/ в https://our.site.ru/bad_cors_com/ и работать безо всяких корсов.
Лучше всего для этих целей подходит nginx, но на apache и iis так же, можно настроить.
9. vandalsvq 1412 04.09.15 01:58 Сейчас в теме
(8), вот это я уже не понял.
У администратора веб-сервера, всегда есть возможность подклеить http://bad.cors.com/ в https://our.site.ru/bad_cors_com/ и работать безо всяких корсов.

Видимо не дорос еще ((.

Сейчас я Access-Control-Allow-Origin в принципе сразу с указанием инициатора возвращаю. Думаю так правильнее как бы.
10. unpete 578 04.09.15 10:49 Сейчас в теме
(9) http://nginx.org/ru/docs/beginners_guide.html там по русски. см. директиву proxy_pass
сразу с указанием инициатора возвращаю

В общем случае, задать инициатора статически не получится. К серверу могут обращаться с разных доменов и есть возможность одним разрешать, а других посылать.

А еще, проверку cors можно отключить в браузере, запустив его с определенными параметрами командной строки. Например, для Chrome: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security
Для того же Chrome, есть директива --allow-cross-origin-auth-prompt - показывает диалог basic-авторизации, если таковая требуется на кроссдоменном сервере.
vandalsvq; +1 Ответить
12. vandalsvq 1412 04.09.15 13:40 Сейчас в теме
(10), (11) unpete, спасибо за все советы. Очень познавательно.
13. vandalsvq 1412 04.09.15 14:50 Сейчас в теме
(10) unpete, что-то мне подсказывает что --disable-web-security не самое лучшее решение. Кстати до кучи еще можно поставить например плагин в хроме, который будет сам заголовок cors подставлять.
14. unpete 578 05.09.15 19:58 Сейчас в теме
(13)
--disable-web-security не самое лучшее решение
Это вовсе не решение для production, но улучшает понимание, что cors - это всего лишь соглашение внутри браузера и к обеспечению реальной безопасности отношения не имеет.
11. unpete 578 04.09.15 10:54 Сейчас в теме
(9) Еще, вспомнил про serviceWorkers. С их помощью, так же, можно кроссдоменные запросы обрабатывать. Причем, вызывающая страница про serviceWorker-а и кроссдомен может ничего не знать. Её xhr будет думать, что работает с локальным сервером, а serviceWorker подменит данные.
faker1980tyumen; +1 Ответить
6. unpete 578 03.09.15 16:36 Сейчас в теме
(2) pahalovo,
системе учета заявок на angular.js

angular, backbone, yui, extjs и т.д. знать и использовать, конечно, необходимо. Это - азбука, без которой невозможно разговаривать.
Для построения production веб-приложений, предлагаю ознакомиться с библиотекой metadata.js большинство ui и data - задач решаются там из коробки без кодирования расстановкой галочек и подготовкой файла описания метаданных
4. pahalovo 01.09.15 01:34 Сейчас в теме
У этого метода есть свои недостатки, но зато это самый быстрый способ включить CORS в существующем api.
Статью можно дополнить описанием механизма "preflight" запросов. В каких случаях эти запросы отправляются и как их правильно обрабатывать на стороне 1С.
Это бы сэкономило много времени тем кто первый раз столкнулся с CORS.

15. Gazz 21.06.17 22:31 Сейчас в теме
HELP!
У меня похожая ситуация - мне нужно отправлять запросы с сайта в http-сервис 1С 8.3.
БД, которая обрабатывает запросы, используют множество пользователей - т.е. без авторизации при подключении к http-сервису никак не обойтись.
GET с Basic авторизацией отрабатывает на ура.
Но когда отправляю этот запрос с браузера - конечно же получаю вначале проверочный запрос OPTIONS. А он уже авторизацию пройти не может.
Подскажите как вырулить из сложившейся ситуации?
Как отправить запросу OPTIONS Ответ = Новый HTTPСервисОтвет(200); без авторизации?
Или все же есть способ заставить его пройти авторизацию?
19. SLV66 31.07.18 19:15 Сейчас в теме
(15) Удалось ли пройти авторизацию?
20. DimonHV 22.08.18 17:57 Сейчас в теме
(19)
- Смотришь какой apache установлен: если 2.2 - сносишь - ставишь 2.4 - в нем есть нормальный оператор if (может можно как-то и в 2.2 сделать - хз)
- Идешь в httpd.conf
- Раскомментируешь модуль mod_headers.so
- Ищешь свою <Directory> и добавляешь хедеры для кроссдоменных запросов (лишнее удаляешь) и оборачиваешь SetHandler в условие:
<Directory "путь_будет_твой"> 
AllowOverride All 
Options None 
Require all granted 
<IfModule mod_headers.c> 
Header always set Access-Control-Allow-Origin "*" 
Header always set Access-Control-Max-Age "1000" 
Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding" 
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT" 
</IfModule> 

<If "(%{REQUEST_METHOD} != 'OPTIONS')"> 
SetHandler 1c-application 
ManagedApplicationDescriptor "путь_будет_твой" 
</If> 

</Directory>
Показать


Теперь проверочный запрос получит пустой ответ с 200 статусом без авторизации, а нужный запрос пойдет с авторизацией.

При повторной публикации настройки apache перетрутся - нужно будет заново обновить конфиг (пока не курил как можно избежать этого).

p.s. ajax Basic авторизация для кириллицы:
'Authorization': 'Basic ' + btoa(unescape(encodeURIComponent('Пользователь' + ':' + 'Пароль')))
suepifanov; KostyaLavr; +2 Ответить
16. Biilsun 03.04.18 11:30 Сейчас в теме
Пытался потобное сделать не получилось, использую ISS
добавил в POST ответ

 Ответ = Новый HTTPСервисОтвет(200);
    Ответ.Заголовки.Вставить("Access-Control-Allow-Origin", "http://localhost:63342");
    Ответ.Заголовки.Вставить("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, HEAD, OPTIONS");
    Ответ.Заголовки.Вставить("Access-Control-Allow-Credentials", "true");
    Ответ.Заголовки.Вставить("Access-Control-Allow-Headers", "X-Requested-With, origin, content-type, accept");


также в конфигурационный файл добавил
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>

по прежнему ошибка 401
17. SLV66 19.07.18 08:46 Сейчас в теме
(16)
Ответ.Заголовки.Вставить("Access-Control-Allow-Credentials", "true");


Получилось ли победить?
18. Biilsun 31.07.18 15:16 Сейчас в теме
(17) да победил, нужно в ISS кросдаоменные запросы еще разрешить
21. mm.krasko 11.09.18 10:53 Сейчас в теме
(18) если не секрет, как всключили? в файле web.config уже указал все что можно, но запрос options дает отлуп по 401 ошибке
22. ECartman 1 16.10.18 16:38 Сейчас в теме
(21) Если актуально.

1) В web.config ничего писать не обязательно (по крайней мере я у себя ничего там не прописывал). Достаточно указать в заголовки ответа

Ответ.Заголовки.Вставить("Access-Control-Allow-Origin", "");
Ответ.Заголовки.Вставить("Access-Control-Allow-Headers", "*");

2) Добавить метод OPTIONS в нужном шаблоне с ответом 200. Ну и не забыть для OPTIONS указать такие же заголовки
23. narus1 22.11.18 02:13 Сейчас в теме
По поводу публикации можно просто обновлять файл *.vrd без обновления сервера.
По поводу заголовков
Ответ.Заголовки.Вставить("Access-Control-Allow-Origin", "");
это только для REST запросов и без авторизации, для Soap не прокатит.
*REST запросов и без авторизации- так как запрос options идет без заголовка "Authorization", и 1с не авторизовывает и кидает ошибку 401
24. Ghost-1_ 29.12.18 07:42 Сейчас в теме
Такая же ситуация не могу авторизоваться. JavaScript

что я не так делаю?

let body = {
data:'14.12.2018',
smena:'Смена Дневная'
};

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open('POST', serviceURL , true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8"');
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('Authorization', "BASIC "+window.btoa(unescape(encodeURIComponent(user+":"+pass))));
xhr.on readystatechange = function() {
if (this.readyState === 4) {
if (this.status === 200) {
alert(this.responseText);
} else {
console.log('ошибка '+this.responseText);
}
}
};
var formData = JSON.stringify(body);
xhr.send(formData);

в iis 8.5 добавил все эти заголовки вместо 1С
"Access-Control-Allow-Origin", "http://localhost:8383");
"Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, HEAD, OPTIONS");
"Access-Control-Allow-Credentials", "true");
"Access-Control-Allow-Headers", "X-Requested-With, origin, content-type, accept");

выходит ошибка
OPTIONS http://192.168.1.40/HTTP_PRR/hs/prr 401 (Unauthorized)
Access to XMLHttpRequest at 'http://192.168.1.40/HTTP_PRR/hs/prr' from origin 'http://localhost:8383' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
25. Ghost-1_ 09.01.19 10:49 Сейчас в теме
GENERAL
Request URL: http://192.168.1.40/HTTP_PRR/hs/prr
Request Method: OPTIONS
Status Code: 401 Unauthorized
Remote Address: 192.168.1.40:80
Referrer Policy: no-referrer-when-downgrade

Response Headers
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Origin, X-Olaround-Debug-Mode, Authorization, Accept, WWW-Authenticate
Access-Control-Allow-Methods: GET, POST, DELETE, HEAD, PUT, OPTIONS
Access-Control-Allow-Origin: http://localhost:8383
Access-Control-Expose-Headers: X-Olaround-Debug-Mode, X-Olaround-Request-Start-Timestamp, X-Olaround-Request-End-Timestamp, X-Olaround-Request-Time, X-Olaround-Request-Method, X-Olaround-Request-Result, X-Olaround-Request-Endpoint
Cache-Control: private
Content-Length: 6293
Content-Type: text/html; charset=utf-8
Date: Wed, 09 Jan 2019 07:01:13 GMT
Server: Microsoft-IIS/8.5
WWW-Authenticate: Basic realm="1C:Enterprise 8.3"
X-Powered-By: ASP.NET

Request Headers
! Provisional headers are shown
Access-Control-Request-Headers: authorization,content-type
Access-Control-Request-Method: POST
Origin: http://localhost:8383
Referer: http://localhost:8383/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
26. pesttt 13.01.19 11:30 Сейчас в теме
(25) Удалось победить? Такая же проблема :(
28. Ghost-1_ 13.01.19 13:59 Сейчас в теме
(26) нет не удалось. пока работаю на серваке где публикуется база 1С.
29. Ghost-1_ 14.01.19 12:51 Сейчас в теме
27. пользователь 13.01.19 11:53
Сообщение было скрыто модератором.
...
30. FreeArcher 153 06.05.19 12:36 Сейчас в теме
Подскажите, как выполнить ajax запрос к 1С авторизацией. Выпадает в ошибку, ни могу победить.
Прикрепленные файлы:
31. user605285_s.panasovskiy 27.04.20 22:50 Сейчас в теме
Нашел простое решение.

1. В HTTP-сервисе добавляем к каждому POST запросу дополнительный метод OPTIONS, который отвечает с заголовками:

"Access-Control-Allow-Origin", "*"
"Access-Control-Allow-Methods", "POST"
"Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization"

2. Добавляем в конфигурацию новую роль, что-то типа "Анонимный". Роли даем права на все Preflight-запросы (они же OPTIONS) в нашем HTTP-сервисе.
2. Создаем нового пользователя в базе, даем ему роль "Анонимный" и устанавливаем ему доменную аутентификацию пользователя \\NT AUTHORITY\IUSR (это пользователь под которым работает служба IIS). Если у вас она запущена под другим пользователем, надо указать его.

И вуаля - Preflight запросы проходят без авторизации, а нужные с авторизацией :)
aign1; sviriduk; +2 Ответить
32. www1 07.05.20 14:23 Сейчас в теме
(31) Бился два дня. Вычитал, что браузеры отправляя OPTIONS намеренно вырезают Authorization заголовок. Хостинг чужой, настройка вэб-сервера недоступна. Полный абзац.

Спасибо Вам, добрый человек. Ваше решение, единственно работающее для меня )
33. vasilievil 528 16.01.22 09:50 Сейчас в теме
Apache 2.4 + 1C OData REST + JavaScript + Chrome

httpd.conf
--------------------------------------
LoadModule headers_module modules/mod_headers.so
LoadModule rewrite_module modules/mod_rewrite.so

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "origin, content-type, authorization"
Header always set Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Header always set Access-Control-Allow-Credentials true

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
34. user1490962 12.01.23 11:29 Сейчас в теме
(33) а на iis ? =)
Оставьте свое сообщение