MSXML2.XMLHTTP 发送方法适用于早期绑定,后期绑定失败

Posted

技术标签:

【中文标题】MSXML2.XMLHTTP 发送方法适用于早期绑定,后期绑定失败【英文标题】:MSXML2.XMLHTTP send method works with early binding, fails with late binding 【发布时间】:2010-09-23 10:57:00 【问题描述】:

下面的代码有效。但是,如果我注释掉 Dim objRequest As MSXML2.XMLHTTP 行并取消注释 Dim objRequest As Object 行,它会失败并显示错误消息:

参数不正确

为什么,我能做些什么(如果有的话)?

Public Function GetSessionId(strApiId, strUserName, strPassword) As String

    Dim strPostData As String

    Dim objRequest As MSXML2.XMLHTTP
    'Dim objRequest As Object '

    strPostData = "api_id=" & strApiId & "&user=" & strUserName & "&password=" & strPassword

    Set objRequest = New MSXML2.XMLHTTP
    With objRequest
        .Open "POST", "https://api.clickatell.com/http/auth", False
        .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
        .send strPostData
        GetSessionId = .responseText
    End With

End Function

Corey,是的,我知道我必须这样做才能让我的代码在不引用 MSXML 类型库的情况下工作。这不是这里的问题。无论我是否使用

,使用Dim objRequest As Object时代码都会失败

Set objRequest = NEW MSXML2.XMLHTTP 带有引用,或

Set objRequest = CreateObject("MSXML2.XMLHTTP") 没有引用。

【问题讨论】:

【参考方案1】:

由于某种原因,这可行:

Dim strPostData As String
Dim objRequest As Object

strPostData = "api_id=" & strApiId & "&user=" & strUserName & "&password=" & strPassword

Set objRequest = New MSXML2.XMLHTTP
With objRequest
  .Open "POST", "https://api.clickatell.com/http/auth", False
  .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
  .send (strPostData)
   GetSessionId = .responseText
End With

不要通过字符串连接构建 URL 编码的 strPostData强烈建议使用 URL 编码函数:

strPostData = "api_id=" & URLEncode(strApiId) & _
              "&user=" & URLEncode(strUserName) & _
              "&password=" & URLEncode(strPassword)

VBA 中 URLEncode() 函数的几个选择在此线程中:How can I URL encode a string in Excel VBA?

【讨论】:

很奇怪,解决方案是将 parathensis 添加到 .send (strPostData)。但我只是确认确实如此。 @Bruno:感谢您的确认。我相信对此有一个完全合乎逻辑的解释,一般在 VBA 或 VBA-to-COM 交互或特别是 MSXML2.XMLHTTP 库的某个地方,但我不知道。我确信@Eric Lippert 可以解释。 ;) strPostData 周围添加括号会强制它按值传递。我假设只有当您需要“保护”您的局部变量不被调用的过程更改时,您才会这样做。我不确定为什么该方法本身的行为会有所不同。有关更多信息,请参见此处:***.com/questions/1070863/… @mwolfe02:太好了,感谢您的解释,这在 VB 端是有道理的。我的猜测是:这要么使用 XMLHTTP 库调用不同的重载 send() 方法,要么可能与 ByVal 和 ByRef 参数的内部字符串缓冲差异有关。 @Henrik 如果您也使用它来发布数据,就像上面的代码示例一样,请检查我刚刚所做的答案更新。【参考方案2】:

如果您使用 Dim objRequest As Object 那么您需要编码: 设置 objRequest = CreateObject("MSXML2.XMLHTTP")

【讨论】:

您可以通过发出“New MSXML2.XMLHTTP”来判断。对我来说,这两种方法都有效。【参考方案3】:

我意识到这与上面 Tomalek 的代码几乎相同(归功于您!),但这个问题帮助我找到了解决问题的完整方法(Excel 提交到 php 服务器,然后处理响应) ...因此,如果这对其他人有任何帮助:

Sub Button1_Click2()

Dim objXMLSendDoc As Object
Set objXMLSendDoc = New MSXML2.DOMDocument
objXMLSendDoc.async = False
Dim myxml As String
myxml = "<?xml version='1.0'?><Request>Do Something</Request>"
If Not objXMLSendDoc.LoadXML(myxml) Then
    Err.Raise objXMLSendDoc.parseError.ErrorCode, , objXMLSendDoc.parseError.reason
End If

Dim objRequest As MSXML2.XMLHTTP
Set objRequest = New MSXML2.XMLHTTP
With objRequest
    .Open "POST", "http://localhost/SISADraftCalcs/Test2.php", False
    .setRequestHeader "Content-Type", "application/xml;charset=UTF-16"
    .setRequestHeader "Cache-Control", "no-cache"
    .send objXMLSendDoc
End With

Dim objXMLDoc As MSXML2.DOMDocument
Set objXMLDoc = objRequest.responseXML
If objXMLDoc.XML = "" Then
    objXMLDoc.LoadXML objRequest.responseText
    If objXMLDoc.parseError.ErrorCode <> 0 Then
        MsgBox objXMLDoc.parseError.reason
    End If
End If

Dim rootNode As IXMLDOMElement
Set rootNode = objXMLDoc.DocumentElement

MsgBox rootNode.SelectNodes("text").Item(0).text

End Sub

【讨论】:

以上是关于MSXML2.XMLHTTP 发送方法适用于早期绑定,后期绑定失败的主要内容,如果未能解决你的问题,请参考以下文章

var xmlHttp = new ActiveXObject("MSXML2.XMLHTTP"); 火狐不兼容问题HTML调用ASP实现和数据库同步

js 之 Post发送请求

CORS 和 Origin 标头?

AJAX火狐和谷歌浏览器不兼容

快速创建你xmlhttp的方法

学习Ajax