如何在VBA中获取CGI::Session Cookie?问题代码求助
问题描述
我需要获取网址https://www.kent-web.com/pwd/protect/enter.cgi的Cookie信息,该网站的账号(ID)和密码(PW)均为“guest”。
我编写的VBA代码无法获取任何Cookie信息(浏览器能获取到set-cookie: CGISESSID=,但VBA中Cookie值为空):
Sub Test() Dim sUrl, sRespHeaders, sRespText, aSetHeaders, aList sUrl = "https://www.kent-web.com/pwd/protect/enter.cgi" XmlHttpRequest "POST", sUrl, Array(), "id=guest&pw=guest&login=LOG+IN", sRespHeaders, sRespText '提交账号密码及登录指令 End Sub Sub XmlHttpRequest(sMethod, sUrl, aSetHeaders, sPayload, sRespHeaders, sRespText) Dim aHeader, strCookie With CreateObject("MSXML2.ServerXMLHTTP") .Open sMethod, sUrl, False For Each aHeader In aSetHeaders .SetRequestHeader aHeader(0), aHeader(1) Next .SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" .SetRequestHeader "Connection", "keep-alive" .Send (sPayload) sRespHeaders = .GetAllResponseHeaders '浏览器能拿到set-cookie: CGISESSID=,但VBA中Cookie值为空 sRespText = .ResponseText strCookie = .GetResponseHeader("Set-Cookie") End With End Sub
我用以下C#代码可以成功获取Cookie信息,但需要用VBA实现相同功能:
using System.IO; using System.Net; using System.Text; static void Main(string[] args) { var url = "https://www.kent-web.com/pwd/protect/enter.cgi"; var req = (HttpWebRequest)WebRequest.Create(url); var cookieContainer = new CookieContainer(); req.CookieContainer = cookieContainer; req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; string postData = "id=guest&pw=guest&login=LOG+IN"; var data = Encoding.ASCII.GetBytes(postData); req.ContentLength = data.Length; using (Stream stream = req.GetRequestStream()) { stream.Write(data, 0, data.Length); using (var res = (HttpWebResponse)req.GetResponse()) { CookieCollection cookies = cookieContainer.GetCookies(new System.Uri(url)); } } }
解决方案
原VBA代码无法获取Cookie的核心原因是MSXML2.ServerXMLHTTP默认不会自动管理Cookie容器,而C#的HttpWebRequest通过CookieContainer主动维护了Cookie会话。要在VBA中实现相同功能,可通过调整请求对象或请求流程解决:
修正后的VBA代码
Sub GetSiteCookie() Dim url As String Dim postData As String Dim http As Object Dim cookie As String url = "https://www.kent-web.com/pwd/protect/enter.cgi" postData = "id=guest&pw=guest&login=LOG+IN" ' 创建自动维护Cookie的XMLHTTP对象 Set http = CreateObject("MSXML2.XMLHTTP") ' 先发送GET请求获取初始会话Cookie(部分网站需此步骤建立会话) http.Open "GET", url, False http.Send cookie = http.GetResponseHeader("Set-Cookie") ' 携带初始Cookie发送POST登录请求 http.Open "POST", url, False http.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" http.SetRequestHeader "Cookie", cookie http.Send postData ' 获取登录后的有效Cookie cookie = http.GetResponseHeader("Set-Cookie") ' 输出结果 MsgBox "获取到的Cookie:" & cookie Debug.Print "获取到的Cookie:" & cookie End Sub
代码说明
- 对象选择:使用
MSXML2.XMLHTTP而非MSXML2.ServerXMLHTTP,前者默认启用Cookie自动管理,无需手动维护容器。 - 请求流程:部分网站要求先通过GET请求建立初始会话,获取基础Cookie后,再携带该Cookie提交登录信息,否则服务器不会返回有效会话Cookie。
- Cookie传递:POST请求中携带GET请求获取的初始Cookie,保证会话连续性,服务器才会返回登录后的
CGISESSID。
如果偏好使用MSXML2.ServerXMLHTTP,可通过设置启用Cookie自动处理:
With CreateObject("MSXML2.ServerXMLHTTP") .SetOption 2, 13056 ' 启用Cookie自动存储与发送 .Open "POST", url, False ' 后续请求头设置、发送逻辑... End With
13056是SXH_OPTION_USE_EXISTING_COOKIE与SXH_OPTION_ALLOW_UI的组合值,确保Cookie被正确处理。
内容的提问来源于stack exchange,提问作者HTTPRequest
相关产品推荐
相关产品推荐

