Как сделать POST-запрос к странице, которая может перенаправить на страницу входа - PullRequest
4 голосов
/ 21 мая 2009

Я использую макрос в Outlook VBA для отправки файла через POST на URL:

Set http = New WinHttp.WinHttpRequest
http.Open "POST", UrlToPostTo, False    'True                                          '
http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
http.setRequestHeader "Content-Type", "multipart/form-data; "
http.Send data

Моя проблема в том, что страница, которая примет запрос (в данном случае это страница загрузки файла), защищена аутентификацией - при первоначальном запросе, указанном выше, будет возвращена страница входа вместо самой страницы.

Я попытался определить, появляется ли страница входа в систему, и если да, опубликовать имя пользователя и пароль в качестве переменных формы (я надеюсь, что это эквивалентно тому, как человек вводит имя пользователя и пароль на страницу в веб-браузере).

Итак, шаги:
* запросить URL (включите файл с постом).
* Проверьте, является ли ответ ответной страницей.
* Если так, то в том же сеансе http отправьте имя пользователя и пароль на URL.
* Если сервер теперь обрабатывает исходное сообщение, хорошо, в противном случае я могу опубликовать его снова.

Код выглядит так:

' if the login page comes back, send credentials                                     '
If (InStr(http.ResponseText, "j_password") > 0) Then

    Dim loginData As String
    loginData = "j_username=theusername&j_password=thepassword"

    http.Open "POST", UrlToPostTo, False
    http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    http.setRequestHeader "Content-Type", "multipart/form-data; "
    http.Send loginData
End If

Но когда я делаю это, http.Responsetext все еще остается страницей входа (или снова?).

Есть идеи, что я делаю не так? Мой план даже действителен?

(Это связано с попыткой решить эту проблему )

Ответы [ 4 ]

9 голосов
/ 04 апреля 2015

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

Хитрость:

  • Отключить перенаправления, используя свойство Option , чтобы остановить его двигаться без тебя. (см. комментарии ниже)
  • Перехватить перенаправление на выходе свойства Status и ручкой оттуда.

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

Чтобы использовать пример кода OPs, вы можете сделать свой запрос, как и планировалось, с одним исключением: переменная EnableRedirects, которая должна появиться после открытия соединения (нигде не читала, просто не могла заставить его придерживаться закрытое соединение).

Удачи, "следующий парень"!

    Dim http As WinHttp.WinHttpRequest
    Dim UrlToPostTo As String, UrlRedirectedTo As String

    'Your initial request (assuming lots here)
    Set http = New WinHttp.WinHttpRequest
    http.Open "POST", UrlToPostTo, False
    'Stop it from redirecting automatically, so you can capture it
    http.Option(WinHttpRequestOption_EnableRedirects) = False 'You can also use the collection index instead of the pretty name
    http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    http.setRequestHeader "Content-Type", "multipart/form-data; "
    http.Send

    'Now if you have an active session, you should get your desired content
    'If it redirected you, you'll have a different status, header etc...    

    If http.status = "302" Then
        Dim loginData As String
        'Now lets find out where we're being pointed and POST there
        'This may not be the same url you see in your address bar 
        UrlRedirectedTo = http.GetResponseHeader("Location")
        'Also, you may have to do this again to arrive back at the intended resource    
        loginData = "j_username=theusername&j_password=thepassword"
        http.Open "POST", UrlRedirectedTo, False
        http.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
        http.setRequestHeader "Content-Type", "multipart/form-data; "
        http.Send loginData
    End If

Некоторая информация, которую я нашел полезной в лабиринте MSDN.

Параметры WinHttpRequest (MSDN)

Объект WinHttpRequest (MSDN)

Обработка файлов cookie WinHttp (MSDN)

0 голосов
/ 27 января 2010

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

    Dim doc As WinHttp.WinHttpRequest
    Set doc = New WinHttpRequest

    doc.Open "POST", url, False

    doc.SetRequestHeader "Cookie", "UserID=" & username
    doc.SetRequestHeader "Cookie", "Password=" & password

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

0 голосов
/ 20 сентября 2011

Попробуйте SetCredentials - это может работать для вас, например ::

http.Open "POST", UrlToPostTo, False
http.SetCredentials "YourUsername", "YourPassword", 0
http.Send

Источник: http://www.automateexcel.com/2005/02/11/excel_vba_winhttprequest_with_login_and/

0 голосов
/ 21 мая 2009

Является ли страница входа по тому же URL-адресу, что и страница, на которую вы первоначально отправили? Я не вижу кода, который меняет urlToPostTo

После первой отправки вы можете просмотреть свойство Status вашего запроса. См. RFC , что означает каждый код состояния. Также может помочь использование метода GetAllResponseHeaders для точного определения того, что происходит. Подробнее см. MSDN

.
...