如何解决从 WebBrowser 获取完整的 cookie 列表
我正在尝试在 C# WebBrowser 控件中获取请求后存储的完整 cookie 列表。代码如下:
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace WindowsFormsApplication1
{
public class ExtractHttpOnlyCookie
{
[DllImport("wininet.dll",CharSet = CharSet.Auto,SetLastError = true)]
static extern bool InternetGetCookieEx(string pchURL,string pchCookieName,StringBuilder pchCookieData,ref uint pcchCookieData,int dwFlags,IntPtr lpReserved);
const int INTERNET_COOKIE_HTTPONLY = 0x00002000;
public static string GetGlobalCookies(string url)
{
uint datasize = 100000;
StringBuilder data = new StringBuilder((int)datasize);
if (InternetGetCookieEx(url,null,data,ref datasize,INTERNET_COOKIE_HTTPONLY,IntPtr.Zero) && data.Length > 0)
return data.ToString();
else
return null;
}
}
}
这不起作用。与 Fiddler 的输出相比,缺少许多 cookie。还有其他方法吗?我检查了 WebBrowser 上的每个属性和方法,但没有任何用处。您提供的任何信息将不胜感激。谢谢。
附录
我认为页面上的 JS 可能会在页面加载后添加更多 cookie。这是相当复杂的脚本,所以我还没有分析它。但是我注入了一个函数来运行 document.cookie 并且输出与 wininet.dll 返回的相同。那么情况可能并非如此?如果有帮助,可以提供页面内容和 cookie 数据。
解决方法
根据@Jimi 的建议,这里有一些获取缓存信息的代码。请注意,它会获取所有内容,如果您想要来自特定站点的 cookie 或缓存条目,则必须过滤该列表。
public class ExtractHttpOnlyCookie
{
[DllImport("wininet.dll",CharSet = CharSet.Auto,SetLastError = true)]
static extern bool InternetGetCookieEx(string pchURL,string pchCookieName,StringBuilder pchCookieData,ref uint pcchCookieData,int dwFlags,IntPtr lpReserved);
[DllImport("wininet.dll",SetLastError = true)]
public static extern bool InternetGetCookie(string url,string cookieName,StringBuilder cookieData,ref int size);
[DllImport("wininet.dll",SetLastError = true,EntryPoint = "FindFirstUrlCacheEntryA",CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr FindFirstUrlCacheEntry([MarshalAs(UnmanagedType.LPTStr)] string lpszUrlSearchPattern,IntPtr lpFirstCacheEntryInfo,ref int lpdwFirstCacheEntryInfoBufferSize);
[DllImport("wininet.dll",CharSet = CharSet.Auto)]
public static extern bool FindNextUrlCacheEntry(IntPtr hEnumHandle,IntPtr lpNextCacheEntryInfo,ref int lpdwNextCacheEntryInfoBufferSize);
[DllImport("wininet.dll")]
public static extern bool FindCloseUrlCache(IntPtr hEnumHandle);
const int INTERNET_COOKIE_HTTPONLY = 0x00002000;
const int INTERNET_COOKIE_THIRD_PARTY = 0x10;
const int INTERNET_FLAG_RESTRICTED_ZONE = 0x00020000;
const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
const int ERROR_NO_MORE_ITEMS = 0x103;
[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Auto)]
public struct INTERNET_CACHE_ENTRY_INFO
{
public int dwStructSize;
[MarshalAs(UnmanagedType.LPTStr)] public String lpszSourceUrlName;
[MarshalAs(UnmanagedType.LPTStr)] public String lpszLocalFileName;
public int CacheEntryType;
public int dwUseCount;
public int dwHitRate;
public int dwSizeLow;
public int dwSizeHigh;
public System.Runtime.InteropServices.ComTypes.FILETIME LastModifiedTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ExpireTime;
public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME LastSyncTime;
public IntPtr lpHeaderInfo;
public int dwHeaderInfoSize;
public IntPtr lpszFileExtension;
public int dwExemptDelta;
}
public static string GetGlobalCookies(string url)
{
//uint datasize = 100000;
//StringBuilder data = new StringBuilder((int)datasize);
//if (InternetGetCookieEx(url,null,data,ref datasize,INTERNET_COOKIE_HTTPONLY,IntPtr.Zero) && data.Length > 0)
// return data.ToString();
//else
// return null;
int bufferSize = 0;
FindFirstUrlCacheEntry("cookie:",IntPtr.Zero,ref bufferSize);
int lastBufferSize = bufferSize;
IntPtr bufferHandle = Marshal.AllocHGlobal(lastBufferSize);
IntPtr handle = FindFirstUrlCacheEntry("cookie:",bufferHandle,ref bufferSize);
bool continueFlag = true;
List<INTERNET_CACHE_ENTRY_INFO> cacheItemList = new List<INTERNET_CACHE_ENTRY_INFO>();
INTERNET_CACHE_ENTRY_INFO cacheItem;
Type itemType = typeof(INTERNET_CACHE_ENTRY_INFO);
while (continueFlag)
{
cacheItem = (INTERNET_CACHE_ENTRY_INFO)Marshal.PtrToStructure(bufferHandle,itemType);
cacheItemList.Add(cacheItem);
bufferSize = lastBufferSize;
continueFlag = FindNextUrlCacheEntry(handle,ref bufferSize);
if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS)
break;
if (bufferSize > lastBufferSize)
{
lastBufferSize = bufferSize;
bufferHandle = Marshal.ReAllocHGlobal(bufferHandle,(IntPtr)lastBufferSize);
continueFlag = true;
}
}
FindCloseUrlCache(handle);
Marshal.FreeHGlobal(bufferHandle);
return "";//put output here
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。