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

MGO*_*wen 4 post vba winhttp outlook-vba

我在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
Run Code Online (Sandbox Code Playgroud)

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

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

所以步骤是:
*请求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
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时,http.Responsetext仍然只是登录页面(或者再次?).

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

(这与尝试解决此问题有关)

小智 9

我知道这个线程是古老的,我意识到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
Run Code Online (Sandbox Code Playgroud)

我发现在MSDN迷宫中有用的一些信息.

WinHttpRequest选项(MSDN)

WinHttpRequest对象(MSDN)

Cookie处理WinHttp(MSDN)

  • 谢谢,这个答案非常有帮助,效果很好。 (2认同)

bar*_*owc 0

登录页面与您最初提交的页面的 URL 是否相同?我没有看到任何更改的代码urlToPostTo

第一次发送后,您可能需要查看Status请求的属性。请参阅RFC了解每个状态代码的含义。它还可以帮助使用该GetAllResponseHeaders方法来准确地弄清楚正在发生的事情。有关更多信息,请参阅MSDN