vba - 使用 vba 使用凭据访问 Web 服务
问题描述
我正在为 Access 编写更长的脚本,并且有一次需要检查 Web 服务以获取文件的最新版本(文件名)。此网络服务只能通过具有 URL 的浏览器访问,https://webservice.example.com:1234/Server/test.jsp?parameter=value
然后必须使用标准浏览器用户名密码弹出来进行身份验证。当然,如果我使用类似的东西,我可以跳过这个弹出窗口https://user:password@webservice.example.com:1234/Server/test.jsp?parameter=value
。(请注意,此时与安全性无关,密码只是为了拥有密码而存在,将其存储为明文是完全可以接受的)
目前我已经使用以下工作代码从另一个网站获取信息:
Dim appIE As Object
Dim sURL as String, infoStr as String
Set appIE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}") 'class id of InternetExplorerMedium
sURL = "https://webservice.example.com:1234/Server/test.jsp?parameter=value"
With appIE
.Navigate sURL
.Visible = False
End With
Do While appIE.Busy Or appIE.ReadyState <> 4
DoEvents
Loop
infoStr = appIE.Document.getElementsByTagName("body").item.innerText
但是,如果我像在浏览器中那样将凭据添加到 URL,
sURL = "https://user:password@webservice.example.com:1234/Server/test.jsp?parameter=value"
我将收到以下错误:
运行时错误“-2146697202 (800c000e)”:对象“IWebBrowser2”的方法“导航”失败
如果我添加凭据或有人知道如何以不同的方式执行此操作,有人知道为什么会失败吗?
解决方案
如果您的网站需要基本身份验证,则使用基本身份验证标头进行身份验证相对容易。
我们需要能够对内容进行 Base64 编码,所以首先我们需要为此定义一个辅助函数:
Public Function ToBase64(Bytes() As Byte) As String
Dim XMLElement As Object
Set XMLElement = CreateObject("Msxml2.DOMDocument.6.0").createElement("tmp")
XMLElement.DataType = "bin.base64"
XMLElement.nodeTypedValue = Bytes
ToBase64 = Replace(XMLElement.Text, vbLf, "")
End Function
然后,创建基本身份验证标头的第二个助手:
Public Function CreateBasicAuthHeader(Username As String, Password As String) As String
'Assuming ASCII encoding, UTF-8 is harder
CreateBasicAuthHeader = "Authorization: Basic " & ToBase64(StrConv(Username & ":" & Password, vbFromUnicode))
End Function
快速验证显示?CreateBasicAuthHeader("Aladdin", "OpenSesame")
返回Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
,这是根据Wikipedia的预期标题
然后,您可以在Navigate
方法中使用它:
Dim appIE As Object
Dim sURL as String, infoStr as String
Set appIE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}") 'class id of InternetExplorerMedium
sURL = "https://webservice.example.com:1234/Server/test.jsp?parameter=value"
With appIE
.Navigate sURL, Headers:=CreateBasicAuthHeader("MyUsername", "MyPassword")
.Visible = False
End With
Do While appIE.Busy Or appIE.ReadyState <> 4
DoEvents
Loop
infoStr = appIE.Document.getElementsByTagName("body").item.innerText
这假定服务器需要 ASCII 编码,或者您的用户名和密码都只是 ASCII 字符并且服务器需要 UTF-8 编码。
推荐阅读
- node.js - 使用 pracrand 测试 RNG 的 nodejs JavaScript 堆内存不足
- python-3.x - 如何从python 3中的字符串数据框中找到出现次数最多的句子
- javascript - Google Drive API 压缩文件损坏
- offline - 离线使用 Cartopy 地图
- python - 在按钮中创建图像
- java - 如何使用 Selenium Webdriver 和 Java 提取元素的显示属性
- python - 如何升级pip?
- c++ - 如何在 C++ 中循环遍历类对象
- syntax - 了解函数类型签名
- arrays - R 将矩阵重塑为多维数组,用于卷积神经网络训练