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

Posted

技术标签:

【中文标题】如何向可能重定向到登录页面的页面发出 POST 请求【英文标题】:How to make a POST request to a page that may redirect to a login page 【发布时间】:2010-10-27 20:18:06 【问题描述】:

我在 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 仍然只是登录页面(或再次?)。

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

(这与尝试解决this problem有关)

【问题讨论】:

【参考方案1】:

我知道这个线程是古老的,我意识到 OP 很早就开始了。我刚刚花了 3 个晚上的大部分时间都被这个完全相同的问题所困扰,当我停下来进行更多研究时,这个帖子不断出现,所以我想我会为下一个出现的人做出贡献。

诀窍是:

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

我确信还有其他方法,但这对我来说似乎很优雅,我发现了很多其他方法来使用它。

要使用 OPs 代码示例,您可以按计划提出请求,但有一个例外: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)

【讨论】:

【参考方案2】:

试试 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】:

您可以将用户名和密码存储在 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 之类的工具来检查标头,以了解您需要做什么。

【讨论】:

【参考方案4】:

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

的代码

第一次发送后,您可能需要查看请求的 Status 属性。请参阅the RFC 了解每个状态代码的含义。它还可以帮助使用GetAllResponseHeaders 方法来准确计算发生了什么。有关更多信息,请参阅MSDN

【讨论】:

登录页面 URL 相同 - 我正在请求原始页面,如果我已经通过身份验证,它正在提供原始页面,否则登录页面。我似乎没有被重定向,手动执行时浏览器中的 URL 不会改变。 @barrowc,谢谢,我会按照建议尝试检查状态和标题。

以上是关于如何向可能重定向到登录页面的页面发出 POST 请求的主要内容,如果未能解决你的问题,请参考以下文章

如果登录成功,如何将用户从登录页面重定向到另一个反应页面?

如何重定向到 html 页面并将变量传递给 Java 中的该页面?

使用 Spring Security 登录后重定向到不同的页面

如何在 IBM Worklight 中重定向到同一页面但不同的 div/视图?

成功登录重定向到登录页面

从同一登录页面使用其用户角色将用户重定向到仪表板