【问题标题】:How does one create an http post call with Excel VBA?如何使用 Excel VBA 创建 http post call?
【发布时间】:2014-12-08 20:37:03
【问题描述】:

我可以通过调用以下代码轻松地进行 GET:

Dim theURL As String, theRequest As Object
theURL = "http://localhost/myapp/encrypt.jsp?str=" & _
    encodeStr(range("I10").Value) & "&user=myUser&pass=myPass"
Set theRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
theRequest.Open "GET", theURL 
theRequest.Send
MsgBox theRequest.ResponseText

但是,我在发布帖子时遇到了更多麻烦。我试图模拟的表单的 html 是:

<form method="post" enctype="multipart/form-data" action="managefile?operation=upload">
  <table>
    <tr>
        <h3 align="center">Upload File</h3>
    </tr>
    <tr>
        <td>File:</td>
        <td><input type="file" size="80" name="fname"></td>
        <td><input type="Submit" value="Upload"></td>
    </tr>
  </table>
</form>

get API 通常期望用户名和密码作为参数传递。由于我认为我不能传递带有参数的 POST,因此我尝试使用我在各个页面(包括此处)上找到的技术发送带有按边界分割的数据的帖子。这些都没有奏效。

这是我尝试过的一些代码的示例,但它不起作用:

Dim theURL As String, theRequest As Object, theBody As String, theBoundary As String
theBoundary = "-----------------13850284693" ' Sample, generating from timestamp        
theBody = theBoundary & vbCrLf
theBody = theBody & "Content-Disposition: form-data" & vbCrLf & vbCrLf
theBody = theBody & "user=myUser&pass=MyPass" & vbCrLf ' I am wondering if this also needs to include action
theBody = theBody & theBoundary & vbCrLf
theBody = theBody & "Content-Disposition: form-data; name=""fname""; filename=""update.xml""" & vbCrLf
theBody = theBody & "Content-Type: text/xml" & vbCrLf & vbCrLf
theBody = theBody & "<MyXML><Node1>ff</Node1></MyXML>"
theBody = theBody & vbCrLf
theBody = theBody & theBoundary & "--" & vbCrLf

theURL = "http://localhost/myapp/managefile?operation=upload"
Set theRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
theRequest.Open "POST", theURL, False
theRequest.setRequestHeader "Cache-Control", "no-cache"
theRequest.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & theBoundary
theRequest.setRequestHeader "Content-Length", Len(theBody)    
theRequest.Send theBody

我从这个例子返回的页面是我没有登录,所以它似乎没有正确传递我的参数。

我也尝试将用户名和密码作为 URL 的一部分传递,例如

theURL = "http://localhost/myapp/managefile?operation=upload&user=myUser&pass=myPass"

从这里我得到一个错误,说它(API)期望

<MyXML>...</MyXML>

它正在变得:

-----------------13850284693..(continues)..<MyXML><Node1>ff</Node1></MyXML>.

这让我相信它可以正常登录但没有正确发布帖子。

我尝试做同样的事情,只是发送 XML,但这也没有用。这对我来说没有意义,因为 API 不知道将 XML 关联到哪个参数。

我尝试的最后一件事是运行一个简单的 get,它让用户登录并返回 cookie,然后将其传回。这似乎和上面做的一样,POST仍然有问题。

这是我设置 cookie 的尝试。它似乎与我传递参数时的工作方式相同——看起来登录有效,但无法正确发布(特别是我尝试发送的 xml):

Dim theLoginRequest, thePostRequest
Set theLoginRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
theLoginRequest.Open "GET", "localhost/myapp/login?user=myUser&pass=myPass"
theLoginRequest.Send
Set thePostRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
thePostRequest.Open "POST, "<post request>", False
thePostRequest.setRequestHeader "Cookie", theLoginRequest.getResponseHeader("Set-Cookie")

...等等。


我在其中的字符串与我能够毫无问题地上传到表单的文件内容相同。

有什么想法吗?

【问题讨论】:

    标签: vba excel post winhttp winhttprequest


    【解决方案1】:

    该网站使用基于 cookie 的登录。因此,您需要使用 GET 登录,获取返回的 cookie,然后在 POST 请求的标头中包含相同的 cookie。

    【讨论】:

    • 感谢汤姆的帮助。我确实尝试过这个,但它似乎没有用。我试过这样的代码: Dim theLoginRequest, thePostRequest Set theLoginRequest = CreateObject("WinHttp.WinHttpRequest.5.1") theLoginRequest.Open "GET", "localhost/myapp/…" theLoginRequest.Send Set thePostRequest = CreateObject("WinHttp.WinHttpRequest.5.1") thePostRequest.Open "POST, "", False thePostRequest.setRequestHeader "Cookie", theLoginRequest.getResponseHeader("Set-Cookie") ...等。结果 = 类似于将登录参数传递给 url。
    • 哇 - 在 cmets 中没有发布代码,好的,我会将其添加到我的主要帖子中以便于阅读。
    猜你喜欢
    • 2010-09-14
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多