5

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

4 回答 4

10

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

诀窍是:

  • 使用Option属性禁用重定向,以阻止它在没有您的情况下继续前进。(见下面的评论)
  • 在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 选项 (MSDN)

WinHttpRequest 对象 (MSDN)

Cookie 处理 WinHttp (MSDN)

于 2015-04-04T00:59:54.413 回答
0

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

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

于 2009-05-21T17:49:04.273 回答
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之类的工具来检查标头,以查看需要做什么。

于 2010-01-27T11:14:59.750 回答
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/

于 2011-09-20T06:57:01.130 回答