如何向可能重定向到登录页面的页面发出POST请求

时间:2009-05-21 04:53:06

标签: vba post outlook-vba winhttp

我在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

我的问题是接受请求的页面(在这种情况下,文件上传页面)受到身份验证的保护 - 上面的初始请求将返回登录页面而不是页面本身。

我试图检测登录页面是否出现,如果是,则将用户名和密码作为表单变量发布(我希望这相当于人类在Web浏览器中输入用户名和密码进入页面)。

所以步骤是:
*请求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仍然是登录页面(或者再次?)。

知道我做错了什么吗?我的计划是否有效?

(这与尝试解决this problem

有关

4 个答案:

答案 0 :(得分:7)

我知道这个线程是古老的,我知道OP很久以前肯定会移动。我只是花了3个晚上的大部分时间被这个完全相同的问题贬低了,当我停止研究更多时,这个线程不断出现,所以我想我会为下一个出现的人做出贡献。

诀窍是:

  • 使用Option属性禁用重定向,以阻止重定向 没有你,继续前进。 (见下面的评论)
  • 捕获Status属性输出的重定向,然后 从那里处理。

我确定还有其他方法,但这对我来说似乎很优雅,而且我找到了许多其他方法来使用它。

要使用OP代码示例,您可以按计划发出请求,但有一个例外:EnableRedirects var,它必须在打开连接后显示(没有在任何地方读取,只是无法获取它)坚持封闭的连接。)

祝你好运"下一个人"!

    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 Options (MSDN)

WinHttpRequest Object (MSDN)

Cookie Handling WinHttp (MSDN)

答案 1 :(得分:0)

您可以将用户名和密码存储在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 等工具检查标题,以查看您需要执行的操作。

答案 2 :(得分:0)

尝试 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/

答案 3 :(得分:0)

登录页面与您最初提交的网页位于同一网址吗?我没有看到任何更改urlToPostTo

的代码

首次发送后,您可能需要查看请求的Status属性。有关每个状态代码的含义,请参阅the RFC。它还可以帮助您使用GetAllResponseHeaders方法准确计算出正在发生的事情。有关详情,请参阅MSDN