【问题标题】:How can I send an HTTP POST request to a server from Excel using VBA?如何使用 VBA 从 Excel 向服务器发送 HTTP POST 请求?
【发布时间】:2010-09-14 14:10:36
【问题描述】:

从 Excel 电子表格执行 HTTP POST 需要什么 VBA 代码?

【问题讨论】:

    标签: excel vba http post serverxmlhttp


    【解决方案1】:
    Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
    URL = "http://www.somedomain.com"
    objHTTP.Open "POST", URL, False
    objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    objHTTP.send ""
    

    或者,为了更好地控制 HTTP 请求,您可以使用 WinHttp.WinHttpRequest.5.1 代替 MSXML2.ServerXMLHTTP

    【讨论】:

    • 为了更好地控制 HTTP 请求,您可以使用“WinHttp.WinHttpRequest.5.1”而不是“MSXML2.ServerXMLHTTP”
    • 值得注意的是,您还可以通过将“POST”更改为“PUT”来使用它来发出 HTTP PUT。 PUT 的内容进入 .send() 方法。您需要设置的任何其他标头也可以按照 User-Agent 示例中使用的语法来完成。
    • 如果您不使用 Sub 的返回值,请不要在参数周围使用括号:VBA 语法不允许在 Sub 的参数周围使用括号(但函数需要它们),所以这些括号实际上是算术括号用于阐明运算符的优先级。除了误导和不清楚之外,如果参数是对象,这最终可能导致运行时错误。虽然没有明确要求,但通常您会希望使用 HTTP 响应,您可以提到可以通过 objHTTP.responseText 检索。
    • @Leviathan 括号实际上做的不止这些:它们让 VBA 运行时将表达式评估为一个值,然后将它传递给 ByVal 方法 不管方法的签名是否显示ByRef。这就是为什么将它们与没有默认成员的类型的对象变量一起使用会导致运行时错误;并在确实具有默认成员的对象上使用它们,传递该默认成员的值而不是实际对象。
    • 一个 json 有效载荷怎么样......我们如何在发送中传递它?
    【解决方案2】:

    如果您需要它同时在 Mac 和 Windows 上工作,您可以使用 QueryTables:

    With ActiveSheet.QueryTables.Add(Connection:="URL;http://carbon.brighterplanet.com/flights.txt", Destination:=Range("A2"))
        .PostText = "origin_airport=MSN&destination_airport=ORD"
        .RefreshStyle = xlOverwriteCells
        .SaveData = True
        .Refresh
    End With
    

    注意事项:

    • 关于输出...我不知道是否可以将结果返回到调用 VBA 函数的同一单元格。在上面的示例中,结果被写入 A2。
    • 关于输入...如果您希望在更改某些单元格时刷新结果,请确保这些单元格是您的 VBA 函数的参数。
    • 这不适用于没有 VBA 的 Excel for Mac 2008。 Excel for Mac 2011 恢复了 VBA。

    更多细节可以看我关于“using web services from Excel”的完整总结。

    【讨论】:

    • +1:我只在 Windows 上需要它,但跨平台解决方案可能会让其他人受益。
    • 我认为你不能真正访问html代码,你只能获取渲染网页上的信息(不是实际的html代码)
    • +1 表示跨平台解决方案,+1(如果可以的话)表示带有 gist 链接和所有内容的完整摘要。谢谢!!
    • 我必须同时支持 windows 和 mac,这个解决方案是正确的!请注意,当您指定 PostText 时,URL 应处理 POST 请求,否则应处理 GET 请求。
    • 是否可以将结果输出到变量而不是 Range ?需要做一些Json解析。
    【解决方案3】:

    除了Bill the Lizard的回答:

    大多数后端解析原始帖子数据。例如,在 PHP 中,您将拥有一个数组 $_POST,其中将存储发布数据中的各个变量。在这种情况下,您必须使用额外的标头 "Content-type: application/x-www-form-urlencoded":

    Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
    URL = "http://www.somedomain.com"
    objHTTP.Open "POST", URL, False
    objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
    objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
    objHTTP.send "var1=value1&var2=value2&var3=value3"
    

    否则,您必须读取变量"$HTTP_RAW_POST_DATA" 上的原始帖子数据。

    【讨论】:

    • 我正在尝试发布这个请求(带花括号)并得到编译错误...你能帮忙吗:“{”request”:{“carName”:“Honda”,“model” : "1A5"}}"
    • @fiddle 你对那个字符串进行了 URL 编码吗?花括号比引号更不重要(它会终止 VBA 中的字符串)
    【解决方案4】:

    完成其他用户的回复:

    为此,我创建了一个 "WinHttp.WinHttpRequest.5.1" 对象。

    使用 VBA 从 Excel 发送包含一些数据的发布请求:

    Dim LoginRequest As Object
    Set LoginRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
    LoginRequest.Open "POST", "http://...", False
    LoginRequest.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
    LoginRequest.send ("key1=value1&key2=value2")
    

    使用 VBA 从 Excel 发送带有令牌身份验证的 get 请求:

    Dim TCRequestItem As Object
    Set TCRequestItem = CreateObject("WinHttp.WinHttpRequest.5.1")
    TCRequestItem.Open "GET", "http://...", False
    TCRequestItem.setRequestHeader "Content-Type", "application/xml"
    TCRequestItem.setRequestHeader "Accept", "application/xml"
    TCRequestItem.setRequestHeader "Authorization", "Bearer " & token
    TCRequestItem.send
    

    【讨论】:

    • 大卫,一旦您发送请求,您如何阅读响应?
    • 响应在TCRequestItem Object里面,你可以在TCRequestItem.send之后读成:TCRequestItem.ResponseText
    • 拜托,@david.q,那个“token”变量是从哪里来的?
    【解决方案5】:

    您可以通过添加对MSXML 的引用在VBA 项目中使用ServerXMLHTTP

    1. 打开 VBA 编辑器(通常通过编辑宏)
    2. 转到可用参考列表
    3. 检查 Microsoft XML
    4. 点击确定。

    (来自Referencing MSXML within VBA Projects

    ServerXMLHTTP MSDN documentation 包含有关 ServerXMLHTTP 的所有属性和方法的完整详细信息。

    简而言之,它的工作原理基本上是这样的:

    1. 调用open方法连接远程服务器
    2. 致电send发送请求。
    3. 通过responseXMLresponseTextresponseStreamresponseBody 阅读回复

    【讨论】:

    • 该链接使用 jscript,而不是 VBA
    • 谢谢@JohnHenckel。我进行了一些更改以更新该答案。
    【解决方案6】:

    我在使用 MSXML 库然后使用 XMLHttpRequest 对象之前这样做了,请参阅here

    【讨论】:

    • 找不到文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 2021-02-09
    相关资源
    最近更新 更多