C#用WebBrowser与WIN API辅助模拟获取网站完整Cookie
网上找到的可以完整获取Cookie的方法,转载一下希望能帮助更多人. 亲测可用
在Winform中使用WebBrowser控件获取网站的Cookie有时候是不完整的,默认调用Document.Cookie也取不到Cookie,其中就是因为有些网站对于关键Cookie做了保护,为Cookie加上了HttpOnly的属性,HttpOnly可以防止cookie被“读取”,这时我们就需要利用WIN API用来辅助获取网站的完整Cookie了。
1using System;
2using System.ComponentModel;
3using System.Net;
4using System.Runtime.InteropServices;
5using System.Security;
6using System.Security.Permissions;
7using System.Text;
8namespace Freecms
9{
10 internal sealed class NativeMethods
11 {
12 #region enums
13 public enum ErrorFlags
14 {
15 ERROR_INSUFFICIENT_BUFFER = 122,
16 ERROR_INVALID_PARAMETER = 87,
17 ERROR_NO_MORE_ITEMS = 259
18 }
19 public enum InternetFlags
20 {
21 INTERNET_COOKIE_HTTPONLY = 8192, //Requires IE 8 or higher
22 INTERNET_COOKIE_THIRD_PARTY = 131072,
23 INTERNET_FLAG_RESTRICTED_ZONE = 16
24 }
25 #endregion
26 #region DLL Imports
27 [SuppressUnmanagedCodeSecurity, SecurityCritical, DllImport("wininet.dll", EntryPoint = "InternetGetCookieExW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
28 internal static extern bool InternetGetCookieEx([In] string Url, [In] string cookieName, [Out] StringBuilder cookieData, [In, Out] ref uint pchCookieData, uint flags, IntPtr reserved);
29 #endregion
30 }
31 /// <SUMMARY></SUMMARY>
32 /// 取得WebBrowser的完整Cookie。
33 /// 因为默认的webBrowser1.Document.Cookie取不到HttpOnly的Cookie
34 ///
35 public class FullWebBrowserCookie
36 {
37 [SecurityCritical]
38 public static string GetCookieInternal(Uri uri, bool throwIfNoCookie)
39 {
40 uint pchCookieData = 0;
41 string url = UriToString(uri);
42 uint flag = (uint)NativeMethods.InternetFlags.INTERNET_COOKIE_HTTPONLY;
43 //Gets the size of the string builder
44 if (NativeMethods.InternetGetCookieEx(url, null, null, ref pchCookieData, flag, IntPtr.Zero))
45 {
46 pchCookieData++;
47 StringBuilder cookieData = new StringBuilder((int)pchCookieData);
48 //Read the cookie
49 if (NativeMethods.InternetGetCookieEx(url, null, cookieData, ref pchCookieData, flag, IntPtr.Zero))
50 {
51 DemandWebPermission(uri);
52 return cookieData.ToString();
53 }
54 }
55 int lastErrorCode = Marshal.GetLastWin32Error();
56 if (throwIfNoCookie || (lastErrorCode != (int)NativeMethods.ErrorFlags.ERROR_NO_MORE_ITEMS))
57 {
58 throw new Win32Exception(lastErrorCode);
59 }
60 return null;
61 }
62 private static void DemandWebPermission(Uri uri)
63 {
64 string uriString = UriToString(uri);
65 if (uri.IsFile)
66 {
67 string localPath = uri.LocalPath;
68 new FileIOPermission(FileIOPermissionAccess.Read, localPath).Demand();
69 }
70 else
71 {
72 new WebPermission(NetworkAccess.Connect, uriString).Demand();
73 }
74 }
75 private static string UriToString(Uri uri)
76 {
77 if (uri == null)
78 {
79 throw new ArgumentNullException("uri");
80 }
81 UriComponents components = (uri.IsAbsoluteUri ? UriComponents.AbsoluteUri : UriComponents.SerializationInfoString);
82 return new StringBuilder(uri.GetComponents(components, UriFormat.SafeUnescaped), 2083).ToString();
83 }
84 }
85}
调用方法(webBrowser1.Url为webBrowser1控件登陆后包含cookie信息的Url):
1string pCookie=Freecms.FullWebBrowserCookie.GetCookieInternal(webBrowser1.Url, false);