ООО ЭкоЮнит
FAQSearchMemberlistUsergroupsFilesLog inRegisterГлавная
printer-friendly view
 
AuthorMessage
Sergey Gender:Male


Местный босс - администратор


Joined: 06 Jan 2005
Show/Hide

Универсальная функция, позволяющая получить содержимое ответа HTTP-сервера.
Пример использования можно посмотреть в обработке  Отправка данных и загрузка файлов на веб-сервер 8.3.epf из статьи Передача файлов и данных на веб-сервер средствами 1С:Предприятие 8.X методом POST

Code:
// Возвращает содержимое ответа HTTP-сервера, полученного методом GET, в виде строки или двоичных данных
// ** Coded by Sergey (aka Porutchik) * 2014 http://forum.aeroion.ru/cat1/
//
// Параметры
//  СерверПриемник - <Строка> - доменное имя сервера или полный адрес (url) запрашиваемой ссылки.
//                        Может включать протокол (http://, https://) и порт.
//  АдресСтраницы - <Строка> - опционально. Адрес страницы на сервере без протокола (http://, https://),
//                        доменного имени сервера (хоста) и порта.
//                Если не указано, адрес страницы будет извлечён из параметра СерверПриемник
//  ПараметрыСоединения - <Структура> - опционально. Структура, содержащая дополнительные параметры для HTTPСоединение.
//                Назначение ключей:
//                Логин или Пользователь - Тип Строка - Имя пользователя на указанном сервере.
//                Пароль - Тип Строка - Пароль пользователя на указанном сервере.
//                Прокси - Тип ИнтернетПрокси - Прокси, используемый для соединения с сервером.
//                Таймаут - Тип Число - Таймаут осуществляемого соединения и операций, в секундах. 0 - не устанавливать таймаут..
//  ЗаголовкиHTTP  - <Соответствие> - опционально.
//                Заголовки, которые будут отправлены на сервер в виде соответствия: "Заголовок" - "Значение".
//                Если указано, функция возвратит в программу заголовки HTTP-ответа с кодом состояния в ключе StatusCode,
//                имя файла в ключе FileName, url-кодированное имя в ключе EncodeFileName
//  ПолучитьКакДвоичныеДанные - <Булево> - опционально. Определяет, в каком виде получить содержимое ответа сервера
//                            По умолчанию Ложь.
//  ЗащищенноеСоединение - <Булево> - опционально. По умолчанию Ложь.
//                            Если Истина, соединение будет происходить по протоколу https://
//
// Возвращаемое значение:
//   <Строка>, <ДвоичныеДанные> - содержимое ответа сервера, если ресурс найден по указанному адресу.
//
Функция ПолучитьСодержимоеВебАдреса(Знач СерверПриемник, Знач АдресСтраницы = "",
                Знач ПараметрыСоединения = Неопределено, ЗаголовкиHTTP = Неопределено,
                Знач ПолучитьКакДвоичныеДанные = Ложь, Знач ЗащищенноеСоединение = Ложь) Экспорт
    Перем ИмяФайлаОтветаКодированное, ИмяФайлаОтвета, Порт, Логин, Пользователь, Пароль, Прокси, Таймаут;

    Если Не ЗначениеЗаполнено(СерверПриемник) Тогда Возврат Неопределено; КонецЕсли;
    Если ТипЗнч(ЗаголовкиHTTP) <> Тип("Соответствие") Тогда ЗаголовкиHTTP = Новый Соответствие; КонецЕсли;
    Если Найти(Нрег(СерверПриемник), "https://") = 1 Тогда ЗащищенноеСоединение = Истина; КонецЕсли;

    Протокол = ?(Найти(Нрег(СерверПриемник), "https://") = 1 ИЛИ ЗащищенноеСоединение, "https://", "http://");
    Если Лев(НРег(СерверПриемник), СтрДлина(Протокол)) = Протокол Тогда
        СерверПриемник = Сред(СерверПриемник, СтрДлина(Протокол) + 1);
    КонецЕсли;

    Если НЕ ЗначениеЗаполнено(АдресСтраницы) Тогда
        Позиция = Найти(СерверПриемник, "/");
        Если Позиция > 0 Тогда
            АдресСтраницы = Сред(СерверПриемник, Позиция, СтрДлина(СерверПриемник));
            СерверПриемник = Лев(СерверПриемник, Позиция - 1);
        Иначе
            АдресСтраницы = "/";
        КонецЕсли;
    КонецЕсли;

    СерверПриемник = СтрЗаменить(СерверПриемник, "/", "");

    //Выделяем порт из доменного имени
    ПозицияДвоеточия = Найти(СерверПриемник, ":");
    Если ПозицияДвоеточия > 0 Тогда
        Порт = Число(Сред(СерверПриемник, ПозицияДвоеточия + 1));
        СерверПриемник = Лев(СерверПриемник, ПозицияДвоеточия - 1);
    КонецЕсли;

    Если ТипЗнч(ПараметрыСоединения) = Тип("Структура") Тогда
        Для каждого КлючЗначение из ПараметрыСоединения Цикл
            Значение = КлючЗначение.Значение; Выполнить(КлючЗначение.Ключ + " = Значение;");
        КонецЦикла;
        Пользователь = ?(ЗначениеЗаполнено(Пользователь), Пользователь, Логин);
    КонецЕсли;
    НТТР = Новый HTTPСоединение(СерверПриемник, Порт, Пользователь, Пароль, Прокси, Таймаут,
                        ?(ЗащищенноеСоединение, Новый ЗащищенноеСоединениеOpenSSL(), Неопределено));

    //Ответ от сервера получим в возвращаемом значении типа HTTPОтвет
    ОтветHTTP = НТТР.Получить(Новый HTTPЗапрос(АдресСтраницы, ЗаголовкиHTTP)); //
    ОшибкаЗапроса = (ОтветHTTP.КодСостояния >= 400);

    //После получения ответа сервера необходимо проверить статус или код состояния.
    //http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
    //Если сервер вернул один из статусов переадресации
    //301 Moved Permanently («перемещено навсегда») или 302 Moved Temporarily («перемещено временно»),
    //то в этом случае можно попытаться перейти на ресурс, на который переадресовал сервер
    Если ОтветHTTP.КодСостояния = 301 или ОтветHTTP.КодСостояния = 302 Тогда

        Если ОтветHTTP.Заголовки.Количество() > 0 Тогда
            //Адрес страницы переадресации содержится в поле Location заголовка ответа
            АдресСтраницы = ОтветHTTP.Заголовки["Location"]; //
            Если ЗначениеЗаполнено(АдресСтраницы) Тогда
                Если Найти(НРег(АдресСтраницы), "http://") = 0 И Найти(НРег(АдресСтраницы), "https://") = 0 Тогда
                    АдресСтраницы = ?(Лев(АдресСтраницы, 1) = "/", Сред(АдресСтраницы, 2), АдресСтраницы);
                    Если Найти(АдресСтраницы, СерверПриемник + "/") = 0  Тогда
                        АдресСтраницы = Протокол + СерверПриемник + ?(ЗначениеЗаполнено(Порт), ":" + Порт, "") + "/" + АдресСтраницы;
                    КонецЕсли;
                КонецЕсли;

                //Если сервер вернул cookies (http://ru.wikipedia.org/wiki/HTTP_cookie, http://www.faqs.org/rfcs/rfc6265.html?#41;,
                //вставим их в заголовки для передачи на страницу перехода
                Куки = ОтветHTTP.Заголовки["Set-Cookie"];//
                Если ЗначениеЗаполнено(Куки) Тогда ЗаголовкиHTTP.Вставить("Cookie", Куки); КонецЕсли;

                //Рекурсивный вызов
                Возврат ПолучитьСодержимоеВебАдреса(АдресСтраницы, , , ЗаголовкиHTTP, ПолучитьКакДвоичныеДанные, ЗащищенноеСоединение);//

            КонецЕсли;
        КонецЕсли;

    ИначеЕсли ОтветHTTP.КодСостояния >= 100 И ОтветHTTP.КодСостояния <= 200 Тогда
        //Статус ответа в интервале между 100 и 200 Ok говорит о нормальном результате HTTP-запроса
        Если ОтветHTTP.Заголовки.Количество() > 0 Тогда
            ТипСодержимого = ОтветHTTP.Заголовки["Content-Type"];
            //http://ru.wikipedia.org/wiki/Список_MIME-типов
            Если Найти(ТипСодержимого, "text/") = 1 ИЛИ Найти(ТипСодержимого, "/javascript")
                ИЛИ Найти(ТипСодержимого, "+xml") ИЛИ Найти(ТипСодержимого, "/xml") <> 0 ИЛИ Найти(ТипСодержимого, "/json") <> 0 Тогда
                ПолучитьКакДвоичныеДанные = Ложь;
            ИначеЕсли Найти(ТипСодержимого, "image/") = 1 ИЛИ Найти(ТипСодержимого, "video/") = 1 
                ИЛИ Найти(ТипСодержимого, "application/") = 1 ИЛИ Найти(ТипСодержимого, "audio/") = 1 Тогда
                //Если содержимое полученного ответа представляет собой изображение, видео, приложение,
                //возвращаем двоичные данные, так как возвращать в виде строки не имеет смысла.
                ПолучитьКакДвоичныеДанные = Истина;
            КонецЕсли;
            //Некоторые сервера возвращают в типе содержимого имя отданного файла, например image/png; name="Имя файла.png"
            //или отдают в заголовке Content-Disposition: attachment; filename=Имя файла.png (http://www.http11.ru/post.php?post=2)
            Если ОтветHTTP.Заголовки["Content-Disposition"] <> Неопределено Тогда
                ТипСодержимого = ОтветHTTP.Заголовки["Content-Disposition"];
            КонецЕсли;
            ТипСодержимого = СтрЗаменить(СтрЗаменить(ТипСодержимого, """", ""), "'", "");

            //в ключе filename*=UTF-8'' содержится url-кодированное имя файла
            ПозицияИмениФайла = Найти(ТипСодержимого, "filename*=UTF-8");
            Если ПозицияИмениФайла <> 0 Тогда
                ИмяФайлаОтветаКодированное = Сред(ТипСодержимого, ПозицияИмениФайла + СтрДлина("filename*=UTF-8"));
                ПозицияДвоеточия = Найти(ИмяФайлаОтветаКодированное, ";");
                Если ПозицияДвоеточия <> 0 Тогда
                    ИмяФайлаОтветаКодированное = Лев(ИмяФайлаОтветаКодированное, ПозицияДвоеточия - 1);
                КонецЕсли;
            КонецЕсли;

            //в ключе filename= содержится обычное имя файла
            ПозицияИмениФайла = Найти(ТипСодержимого, "name=");
            Если ПозицияИмениФайла <> 0 Тогда
                ИмяФайлаОтвета = Сред(ТипСодержимого, ПозицияИмениФайла + СтрДлина("name="));
                ПозицияДвоеточия = Найти(ИмяФайлаОтвета, ";");
                Если ПозицияДвоеточия <> 0 Тогда
                    ИмяФайлаОтвета = Лев(ИмяФайлаОтвета, ПозицияДвоеточия - 1);
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;

    ЗаголовкиHTTP = ОтветHTTP.Заголовки;
    //Добавляем в заголовки ответа код состояния (ответа) HTTP-сервера и имя файла содержимого, если есть.
    ЗаголовкиHTTP.Вставить("StatusCode", ОтветHTTP.КодСостояния);
    Если ЗначениеЗаполнено(ИмяФайлаОтвета) Тогда ЗаголовкиHTTP.Вставить("FileName", ИмяФайлаОтвета); КонецЕсли;
    Если ЗначениеЗаполнено(ИмяФайлаОтветаКодированное) Тогда
        ЗаголовкиHTTP.Вставить("EncodeFileName", ИмяФайлаОтветаКодированное);
    КонецЕсли;

    Если ОшибкаЗапроса ИЛИ НЕ ПолучитьКакДвоичныеДанные Тогда Возврат ОтветHTTP.ПолучитьТелоКакСтроку(); КонецЕсли;
    Возврат ОтветHTTP.ПолучитьТелоКакДвоичныеДанные();

КонецФункции // ПолучитьСодержимоеВебАдреса()


Примеры использования:

Получение содержимого в виде строки
Code:
СодержимоеАдреса = ПолучитьСодержимоеВебАдреса("http://forum.aeroion.ru/topic446.html");


Получение содержимого в виде строки и с указанием реферера HTTP referer
Code:

ЗаголовкиHTTP = Новый Соответствие;
ЗаголовкиHTTP.Вставить("Referer", "http://some_site.com/");
СодержимоеАдреса = ПолучитьСодержимоеВебАдреса("http://some_site.com/topic.html", , ЗаголовкиHTTP);


Получение содержимого в виде двоичных данных для преобразования в картинку
Code:

СодержимоеАдреса = ПолучитьСодержимоеВебАдреса("http://forum.aeroion.ru/images/away_profile.jpg");
Если ТипЗнч(СодержимоеАдреса) = Тип("ДвоичныеДанные") Тогда
    СодержимоеАдреса.Записать("ИМЯ_ФАЙЛА_НА_ДИСКЕ");
КонецЕсли;


Получение содержимого url-адреса с использованием дополнительных параметров соединения
Code:

ЗаголовкиHTTP = Новый Соответствие;
//Параметры соединения здесь приведены только для примера использования
Прокси = Новый ИнтернетПрокси;
ПараметрыСоединения = Новый Структура("Пользователь,Пароль,Прокси,Таймаут", "123", "234", Прокси, 50);
ПолученныеДанные = ПолучитьСодержимоеВебАдреса(АдресДляПолученияСодержимого, , ПараметрыСоединения, ЗаголовкиHTTP);

ИмяФайлаДляСохранения = "";
Если ЗначениеЗаполнено(ЗаголовкиHTTP["EncodeFileName"]) Тогда
    //Декодируем кодированное имя файла
    Оболочка = Новый COMОбъект("MSScriptControl.ScriptControl");
    Оболочка.Language = "javascript";
    Оболочка.AddCode("function utf8_decode(uriEncode){
            |    return decodeURIComponent(uriEncode);
            |}");
    ИмяФайлаДляСохранения = Оболочка.Run("utf8_decode", ЗаголовкиHTTP["EncodeFileName"]);
Иначе
    ИмяФайлаДляСохранения = ЗаголовкиHTTP["FileName"];
КонецЕсли; 

_________________
Профессионал - это тот же дилетант, только знающий где ошибется. Генератор db_update.php для phpBB2 с некоторыми удобствами.
Как ставить моды. Что такое [SQL] и с чем его едят | Как правильно задавать вопросы и получать адекватные ответы | Правила форума
Бесплатная техподдержка только на форуме! Не надо стучаться в аську, скайп, слать емайлы, пытаться писать в приват. Спасибо за понимание. Please do not PM, ICQ, Skype or email me for support help - you won't get any reply. If you have a question or issue, post it in the appropriate forum/topic. Thanks!
Back to topOffline View user's profile Visit poster's website Skype Name
Display posts from previous:   

Summary Rating For >> Функция. Получение содержимого адреса url (вебстраницы) методом GET для 1С: Предприятия 8.2.18 - 8.3
Average Rating: 5.00 :: Min Rating: 5 :: Max Rating: 5 :: Number of Ratings: 2
Choose Rating: 1   2   3   4   5  


Similar Topics
Topic Author Forum Replies Last Post
No new posts Передача / получение файлов и данных на веб-сервер средствами 1С:Предприятие 8.X методом POS...
взаимодействие с веб-сервером
Moderator message Sergey @ 1390412257 Редакция статьи, переработанной с учетом замечаний, приобретённого опыта, а также с учетом изменений в платформе 8.3. Moderator message В статье собран мой опыт по передаче данных на
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 61 Fri 11 May, 2018 14:16 View latest post
Карпов
No new posts Функция. Определение размера данных для 1С: Предприятия 8.Х
Универсальная функция, позволяющая определить размер данных (хранилища значения, двоичных данных, картинки, строки). Разработана в ходе реализации проекта по взаимодействию с веб-сервером для контроля размера
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Tue 06 Oct, 2009 02:55 View latest post
Sergey
No new posts Запись произвольного адреса в контактную информацию объекта в конфигурациях на БСП версий 2....
контактная информация
При импорте данных, полученных из сторонних источников (текстовый файл, xml, dbf, Excel, etc), иногда встаёт задача записать контактную информацию для объекта базы данных (контрагент, физлицо, etc) в произвольной форме.
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 16 Sat 10 Nov, 2018 15:31 View latest post
Гап
No new posts Функция. Добавление колонки данных в табличное поле формы
для конфигураций 1C: Предприятия 8.X (обычное приложение)
Функция предназначена в основном для изменения типовых конфигураций 1C: Предприятия 8.X линии УТ 10.3, УПП 1.2, БП 2.0, когда хочется что-то добавить, но не хочется сильно менять штатный код и формы. // Добавляет колонку
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 0 Sat 03 Apr, 2010 01:38 View latest post
Sergey
No new posts Функция Русский MetaPhone, Soundex, расстояние Левенштейна и другие для 1С:Предприятия любой...
нечёткий поиск информации
Функция полезна для организации поиска информации в базе данных, например фамилий, по нечёткому совпадению. Портирована с Visual Basic несколько лет назад, в ходе решения задачи по поиску контрагентов или физлиц (уже не
Sergey 1Сv8: Программирование, отчёты, обработки, статьи 2 Sun 16 May, 2010 02:33 View latest post
Sergey






All times are UTC + 3 hours
Users browsing this topic:
Registered Users: None

Jump to:   
printer-friendly view
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum
/a
Username:

Password:

Log me on automatically each visit
  Яндекс.Метрика
CrackerTracker © 2004 - 2018 CBACK.de