如何向可能重定向到登录页面的页面发出 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 登录后重定向到不同的页面