Начало:
1.
Общение с ЖЖ из скрипта по протоколу HTTP(S), ч.1: документация2.
Общение с ЖЖ из скрипта по протоколу HTTP(S), ч.2: URL-адрес входа, интерфейсы Почему не подходит браузер
Большинство пользователей использует в качестве веб-клиента обычный браузер. Попробуем обратиться к ЖЖ по интерфейсам «flat» и «XML-RPC» из браузера. Для этого введем в адресную строку браузера соответствующие URL-адреса входа:
1.
https://www.livejournal.com/interface/flat Получили следующий результат в окне браузера:
errmsg
Client error: No mode specified.
success
FAIL
В
предыдущем посте я описывал формат этой строки, полученной от веб-приложения «LiveJournal». В блоке кода выше мы получили два параметра с именами «errmsg» и «success». Перепишем их в более понятном формате:
errmsg = "Client error: No mode specified."
success = "FAIL"
Второй параметр с названием «success» (по-русски «успех») может принимать два значения: «OK» (если полученный запрос обработан веб-приложением «LiveJournal» успешно) и «FAIL» (обработка полученного запроса веб-приложением «LiveJournal» завершилась неудачей; наш случай). В первом параметре с названием «errmsg» описана причина неудачи: в запросе от веб-клиента (браузера) не определен параметр с названием «mode».
Как я описывал в
предыдущем посте, веб-клиент должен поместить названия и значения параметров запроса в тело HTTP-запроса. Но как это сделать в браузере?
По умолчанию вы не можете в браузере напрямую задать содержимое тела HTTP-запроса. Вы можете лишь задать в адресной строке браузера URL-адрес, по которому браузер отправит HTTP-запрос. Для простого перехода на указанный пользователем в адресной строке браузера URL-адрес браузер отправляет HTTP-запрос по методу «GET»; в таком HTTP-запросе вообще нет тела HTTP-запроса. При отправке данных HTML-формы на веб-сервер браузер отправляет HTTP-запрос по методу «POST», в котором присутствует тело HTTP-запроса, автоматически заполняемое данными из HTML-формы (тело HTTP-запроса в данном случае заполняется браузером, вы можете лишь менять данные в HTML-форме).
Таким образом, браузер по умолчанию не дает нам достаточного контроля над HTTP-запросом, чтобы работать с ЖЖ по интерфейсу «flat» (или по интерфейсу «XML-RPC»). Возможно, существуют какие-то браузерные расширения, дающие необходимые возможности, но я предпочитаю не иметь дела с браузерными расширениями, так как они
бывают небезопасны.
2.
https://www.livejournal.com/interface/xmlrpc На этот URL-адрес, введенный в адресной строке браузера, я получил от веб-приложения «LiveJournal» HTTP-ответ с кодом состояния 200 (запрос обработан успешно), но в этом HTTP-ответе отсутствовало тело (content). Окно браузера осталось пустым. Причина отсутствия ответа на запрос в теле HTTP-ответа, думаю, та же, что и в случае с HTTP-запросом по интерфейсу «flat», описанному выше: в запросе не переданы нужные параметры (для данного интерфейса они должны были быть в формате XML).
Тексты отправленного HTTP-запроса и полученного HTTP-ответа в браузере можно просмотреть в инструменте «Network» инструментов разработчика (в моем браузере инструменты разработчика для текущей вкладки браузера вызываются клавишей «F12» с клавиатуры).
Командлет «Invoke-WebRequest» программы-оболочки «PowerShell»
В принципе, существует множество подходящих веб-клиентов. Выбор зависит от языка программирования, на котором вы хотите писать свой скрипт (программу) для общения с ЖЖ. Мне сейчас интересен язык программирования «PowerShell» и одноименная программа-оболочка. Я работаю в операционной системе «Windows 10» и использую программу-оболочку «PowerShell» версии 7. В этой программе-оболочке существует известный командлет «
Invoke-WebRequest» для формирования и отправки HTTP-запросов и получения HTTP-ответов прямо из командной строки. Для задач посложнее на языке «PowerShell» можно написать скрипт. Таким образом, для общения с ЖЖ из скрипта я выбираю этот инструмент.
Повторим вышеописанный опыт с браузером в программе-оболочке «PowerShell»:
PS C:\> $Response = Invoke-WebRequest -URI "
https://www.livejournal.com/interface/flat"
PS C:\> $Response.Content
errmsg
Client error: No mode specified.
success
FAIL
Ответ мы получили тот же, что и в браузере. Однако, в отличие от браузера в командлете «Invoke-WebRequest» мы можем прямо формировать разные части HTTP-запроса (в том числе и тело HTTP-запроса) через параметры этого командлета. Разных параметров у него довольно много.
Что получает веб-приложение от командлета «Invoke-WebRequest»
Как я понял, у командлета «Invoke-WebRequest» есть небольшой недостаток: мы не видим итогового текста отправляемого HTTP-запроса, хоть и можем формировать отдельные его части (HTTP-ответ полностью доступен, в блоке кода выше он сохранен в переменной $Response). Конечно, в скрипте на языке «PowerShell» мне доступны классы платформы «.NET» вроде «
System.Net.HttpWebRequest» или «
System.Net.Http.HttpClient», которые дают более свободный доступ к тексту HTTP-запроса, но пока что я решил обойтись командлетом «Invoke-WebRequest».
Хорошо, мы не можем видеть, в каком виде командлет «Invoke-WebRequest» отправляет HTTP-запрос. Но, ведь, я могу зайти с другой стороны пары клиент-сервер, то есть со стороны веб-сервера, и посмотреть, что получает веб-сервер (это и будет то, что отправил командлет «Invoke-WebRequest»).
Недавно я
начал работать с веб-севером «IIS» версии 10 и с интерпретатором PHP у себя на компьютере локально. Я решил написать простую модель веб-приложения на языке PHP, которая будет получать HTTP-запрос от веб-клиента и сохранять его в текстовом файле (после этого я смогу просмотреть текст этого HTTP-запроса). Вот что у меня получилось:
$header_value) {
$request .= $header_name.": ".$header_value."\n";
}
$request .= "\n".file_get_contents('php://input');
file_put_contents('testFolder\test.txt', $request);
Следует отметить, что веб-приложение на языке PHP не может сразу получить исходный текст HTTP-запроса от веб-клиента, так как сначала его получает веб-сервер (в моем случае «IIS») и сразу разделяет на куски. В итоге веб-приложению доступны только эти куски. Поэтому в коде выше пришлось собирать HTTP-запрос из этих кусков обратно в исходный текст. Напомню,
$_SERVER - это предопределенная встроенная переменная-массив.
Я поместил код из блока кода выше в файл «test.php», который перед этим создал у себя на рабочем столе (это важно: владельцем созданного таким образом файла записывается текущая учетная запись пользователя компьютера). После этого я переместил этот файл в папку «C:\inetpub\wwwroot\» своего локального сайта (для перемещения файла в эту папку требуются права администратора компьютера). Так как моя учетная запись пользователя является владельцем файла «test.php», то я могу его редактировать из редактора «VS Code» (или другого текстового редактора) прямо в папке «C:\inetpub\wwwroot\» из-под своей учетной записи, не поднимая права доступа до прав администратора компьютера.
Если теперь запустить веб-приложение «test.php», то оно не сможет создать папку «testFolder» и файл «test.txt» в этой папке, так как не имеет нужных прав доступа. Напомню, веб-сервер «IIS» версии 10 устроен так, что веб-приложение «test.php» запускается от встроенной учетной записи соответствующего пула приложений (у меня это учетная запись «DefaultAppPool»). Чтобы веб-приложение «test.php» могло создать вышеуказанные папку и файл, у учетной записи «DefaultAppPool» должны быть соответствующие права доступа.
Папку «C:\inetpub\wwwroot\testFolder» я создал вручную (понадобились права администратора компьютера), а затем дал полный доступ к этой папке, ее подпапкам и файлам встроенной учетной записи «DefaultAppPool». Как это сделать, я подробно описывал в
отдельном посте.
Теперь отправляем HTTP-запрос веб-приложению «test.php» с помощью командлета «Invoke-WebRequest»:
PS C:\> $Response = Invoke-WebRequest -URI "
https://localhost/test.php"
В результате этой команды у меня в папке «C:\inetpub\wwwroot\testFolder» появился файл «test.txt» со следующим содержимым:
GET /test.php HTTP/1.1
Content-Type:
Content-Length: 0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.19045; ru-RU) PowerShell/7.3.1
Host: localhost
Это текст HTTP-запроса, полученный веб-приложением «test.php» от командлета «Invoke-WebRequest». Тут можно видеть, как этот командлет формирует HTTP-запрос по умолчанию (в параметрах этого командлета я указал только URL-адрес, остальное он сформировал сам; эти умолчания можно изменить с помощью других параметров этого командлета). Кстати, видно, что по умолчанию тело HTTP-запроса отсутствует. Теперь можно начать экспериментировать с командлетом «Invoke-WebRequest» более подробно.
Продолжение следует.