如何使用 VBA 从 Excel 向服务器发送 HTTP POST 请求?

Posted

技术标签:

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

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

【问题讨论】:

【参考方案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

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

(来自Referencing MSXML within VBA Projects)

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

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

    调用open方法连接远程服务器 致电send发送请求。 通过responseXML、responseText、responseStream 或responseBody 阅读回复

【讨论】:

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

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

【讨论】:

找不到文件。

以上是关于如何使用 VBA 从 Excel 向服务器发送 HTTP POST 请求?的主要内容,如果未能解决你的问题,请参考以下文章

Excel VBA:如何在 Outlook 中向组发送电子邮件?

VBA:将表格从 Excel 发送到 Outlook [重复]

通过 ASP.NET 向用户发送 Excel

VBA如何捕获请求超时错误?

如何使用 Excel VBA 更改系统默认打印机?

vbscript 从Excel发送电子邮件 - VBA