// Возвращает содержимое ответа HTTP-сервера, полученного методом GET, в виде строки или двоичных данных // ** Coded by Sergey (aka Porutchik) * 2014 http://forum.aeroion.ru/cat1.html // // Параметры // СерверПриемник - <Строка> - доменное имя сервера или полный адрес (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.... //Если сервер вернул один из статусов переадресации //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.ПолучитьТелоКакДвоичныеДанные(); КонецФункции // ПолучитьСодержимоеВебАдреса() //Источник: http://forum.aeroion.ru/topic749.html
Примеры использования: