CookieHelper.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Net;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using System.Threading.Tasks;
  9. using System.Web;
  10. using Masuit.Tools.Logging;
  11. namespace Masuit.Tools.Net
  12. {
  13. /// <summary>
  14. /// Cookie操作辅助类
  15. /// </summary>
  16. public static class CookieHelper
  17. {
  18. [DllImport("wininet.dll", SetLastError = true)]
  19. private static extern bool InternetGetCookie(string url, string cookieName, StringBuilder cookieData, ref int size);
  20. /// <summary>
  21. /// 获取Cookie容器
  22. /// </summary>
  23. /// <param name="uri">URL</param>
  24. /// <returns>Cookie容器</returns>
  25. public static CookieContainer GetUriCookieContainer(this Uri uri)
  26. {
  27. CookieContainer cookies = null;
  28. //定义Cookie数据的大小。
  29. int datasize = 256;
  30. StringBuilder cookieData = new StringBuilder(datasize);
  31. if (!InternetGetCookie(uri.ToString(), null, cookieData, ref datasize))
  32. {
  33. if (datasize < 0) return null;
  34. // 确信有足够大的空间来容纳Cookie数据。
  35. cookieData = new StringBuilder(datasize);
  36. if (!InternetGetCookie(uri.ToString(), null, cookieData, ref datasize)) return null;
  37. }
  38. if (cookieData.Length > 0)
  39. {
  40. cookies = new CookieContainer();
  41. cookies.SetCookies(uri, cookieData.ToString().Replace(';', ','));
  42. }
  43. return cookies;
  44. }
  45. /// <summary>
  46. /// 获取url下的Cookie
  47. /// </summary>
  48. /// <param name="cookies">Cookie对象</param>
  49. /// <param name="uri">URL</param>
  50. /// <returns>Cookie内容</returns>
  51. public static string PrintCookies(this CookieContainer cookies, Uri uri)
  52. {
  53. CookieCollection cc = cookies.GetCookies(uri);
  54. StringBuilder sb = new StringBuilder();
  55. foreach (Cookie cook in cc)
  56. {
  57. sb.AppendLine(string.Format("{0}:{1}", cook.Name, cook.Value));
  58. }
  59. return sb.ToString();
  60. }
  61. #region 清除CooKie
  62. #region 清除指定Cookie
  63. /// <summary>
  64. /// 清除指定Cookie
  65. /// </summary>
  66. /// <param name="cookiename">cookiename</param>
  67. public static void ClearCookie(string cookiename)
  68. {
  69. HttpCookie cookie = HttpContext.Current.Request.Cookies[cookiename];
  70. if (cookie != null)
  71. {
  72. cookie.Expires = DateTime.Now.AddYears(-3);
  73. HttpContext.Current.Response.Cookies.Add(cookie);
  74. }
  75. }
  76. #endregion
  77. #region 删除所有cookie值
  78. /// <summary>
  79. /// 删除所有cookie值
  80. /// </summary>
  81. public static void Clear()
  82. {
  83. int n = HttpContext.Current.Response.Cookies.Count;
  84. for (int i = 0; i < n; i++)
  85. {
  86. HttpCookie MyCookie = HttpContext.Current.Response.Cookies[i];
  87. MyCookie.Expires = DateTime.Now.AddDays(-1);
  88. HttpContext.Current.Response.Cookies.Add(MyCookie);
  89. }
  90. }
  91. #endregion
  92. #region 清除系统指定的Cookie
  93. /// <summary>
  94. /// 清除系统指定的Cookie
  95. /// </summary>
  96. /// <param name="ck">指定的Cookie</param>
  97. /// <param name="url">Cookie的域</param>
  98. public static void ClearCookies(string ck, string url)
  99. {
  100. string[] cks = GetCKS(ck);
  101. List<string> domains = GetDomains(url);
  102. for (int i = 0; i < cks.Length; i++)
  103. {
  104. string[] nv = cks[i].Split('=');
  105. for (int j = 0; j < domains.Count; j++)
  106. {
  107. InternetSetCookie(domains[j], nv[0], "abc;expires = Sat, 31-Dec-2007 14:00:00 GMT");
  108. }
  109. }
  110. }
  111. #endregion
  112. #region 清除系统的Cookie文件
  113. /// <summary>
  114. /// 清除系统的Cookie文件
  115. /// </summary>
  116. public static void ClearCookiesFiles()
  117. {
  118. DirectoryInfo di = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Cookies));
  119. foreach (FileInfo file in di.GetFiles())
  120. {
  121. try
  122. {
  123. file.Delete();
  124. }
  125. catch (Exception e)
  126. {
  127. LogManager.Error(e);
  128. }
  129. }
  130. }
  131. #endregion
  132. #endregion
  133. #region 获取Cookie
  134. #region 获取指定Cookie值
  135. /// <summary>
  136. /// 获取指定Cookie值
  137. /// </summary>
  138. /// <param name="cookiename">cookiename</param>
  139. /// <returns>Cookie值</returns>
  140. public static string GetCookieValue(string cookiename)
  141. {
  142. HttpCookie cookie = HttpContext.Current.Request.Cookies[cookiename];
  143. string str = null;
  144. if (cookie != null)
  145. {
  146. str = cookie.Value;
  147. }
  148. return str;
  149. }
  150. /// <summary>
  151. /// 根据Key值得到Cookie值,Key不区分大小写
  152. /// </summary>
  153. /// <param name="Key">key</param>
  154. /// <param name="cookie">字符串Cookie</param>
  155. /// <returns>Cookie值</returns>
  156. public static string GetCookieValue(string Key, string cookie)
  157. {
  158. foreach (CookieItem item in GetCookieList(cookie))
  159. {
  160. if (item.Key == Key)
  161. return item.Value;
  162. }
  163. return "";
  164. }
  165. /// <summary>
  166. /// 根据字符生成Cookie列表
  167. /// </summary>
  168. /// <param name="cookie">Cookie字符串</param>
  169. /// <returns>Cookie列表</returns>
  170. public static List<CookieItem> GetCookieList(string cookie)
  171. {
  172. List<CookieItem> cookielist = new List<CookieItem>();
  173. foreach (string item in cookie.Split(new[] { ";", "," }, StringSplitOptions.RemoveEmptyEntries))
  174. {
  175. if (Regex.IsMatch(item, @"([\s\S]*?)=([\s\S]*?)$"))
  176. {
  177. Match m = Regex.Match(item, @"([\s\S]*?)=([\s\S]*?)$");
  178. cookielist.Add(new CookieItem() { Key = m.Groups[1].Value, Value = m.Groups[2].Value });
  179. }
  180. }
  181. return cookielist;
  182. }
  183. #endregion
  184. #region 获取cookie数组
  185. /// <summary>
  186. /// 获取cookie数组
  187. /// </summary>
  188. /// <param name="ck">cokki数据</param>
  189. /// <returns>字符串数组</returns>
  190. public static string[] GetCKS(string ck)
  191. {
  192. if (ck != null)
  193. {
  194. return ck.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
  195. }
  196. else
  197. {
  198. return new string[0];
  199. }
  200. }
  201. #endregion
  202. #region 从Cookie数组中转换成不重复的Cookie字符串,相同的Cookie取前面的
  203. /// <summary>
  204. /// 从Cookie数组中转换成不重复的Cookie字符串,相同的Cookie取前面的
  205. /// </summary>
  206. /// <param name="cks">Cookie数组</param>
  207. /// <returns>剔除重复的Cookie字符串</returns>
  208. public static string GetCK(string[] cks)
  209. {
  210. string res = "";
  211. List<string> list = new List<string>();
  212. for (int i = 0; i < cks.Length; i++)
  213. {
  214. if (cks[i].Trim() != "")
  215. {
  216. if (!IncludeCKAsync(list, cks[i]).Result)
  217. {
  218. list.Add(cks[i].Trim());
  219. }
  220. }
  221. }
  222. for (int i = 0; i < list.Count; i++)
  223. {
  224. res += list[i] + ";";
  225. }
  226. return res;
  227. }
  228. #endregion
  229. #region 从CookieCollection中获取Cookie字符串
  230. /// <summary>
  231. /// 从CookieCollection中获取Cookie字符串
  232. /// </summary>
  233. /// <param name="cc">CookieCollection,一般用在WebRequest中</param>
  234. /// <returns>转换后的Cookie字符串</returns>
  235. public static string GetCK(this CookieCollection cc)
  236. {
  237. string ck = "";
  238. for (int i = 0; i < cc.Count; i++)
  239. {
  240. ck += cc[i].Name + "=" + cc[i].Value + ";";
  241. }
  242. return ck;
  243. }
  244. #endregion
  245. #region 将Cookie字符串填充到CookieCollection中
  246. /// <summary>
  247. /// 将Cookie字符串填充到CookieCollection中
  248. /// </summary>
  249. /// <param name="ck">Cookie字符串</param>
  250. /// <param name="url">Cookie的域</param>
  251. /// <returns>添加后的CookieCollection</returns>
  252. public static CookieCollection GetCK(string ck, string url)
  253. {
  254. CookieCollection cc = new CookieCollection();
  255. string domain = "";
  256. try
  257. {
  258. Uri u = new Uri(url);
  259. domain = u.Host;
  260. }
  261. catch (Exception e)
  262. {
  263. LogManager.Error(e);
  264. }
  265. string[] cks = GetCKS(ck);
  266. for (int i = 0; i < cks.Length; i++)
  267. {
  268. if (cks[i].IndexOf("=") > -1)
  269. {
  270. try
  271. {
  272. string n = cks[i].Substring(0, cks[i].IndexOf("="));
  273. string v = cks[i].Substring(cks[i].IndexOf("=") + 1);
  274. System.Net.Cookie c = new System.Net.Cookie();
  275. c.Name = n.Trim();
  276. c.Value = v.Trim();
  277. c.Domain = domain;
  278. cc.Add(c);
  279. }
  280. catch (Exception e)
  281. {
  282. LogManager.Error(e);
  283. }
  284. }
  285. }
  286. return cc;
  287. }
  288. #endregion
  289. #endregion
  290. #region 添加Cookie
  291. #region 添加一个Cookie(24小时过期)
  292. /// <summary>
  293. /// 添加一个Cookie(24小时过期)
  294. /// </summary>
  295. /// <param name="cookiename">键</param>
  296. /// <param name="cookievalue">值</param>
  297. public static void SetCookie(string cookiename, string cookievalue)
  298. {
  299. SetCookie(cookiename, cookievalue, DateTime.Now.AddDays(1.0));
  300. }
  301. #endregion
  302. #region 添加一个Cookie
  303. /// <summary>
  304. /// 添加一个Cookie
  305. /// </summary>
  306. /// <param name="cookiename">cookie名</param>
  307. /// <param name="cookievalue">cookie值</param>
  308. /// <param name="expires">过期时间 DateTime</param>
  309. public static void SetCookie(string cookiename, string cookievalue, DateTime expires)
  310. {
  311. HttpCookie cookie = new HttpCookie(cookiename)
  312. {
  313. Value = cookievalue,
  314. Expires = expires
  315. };
  316. HttpContext.Current.Response.Cookies.Add(cookie);
  317. }
  318. #endregion
  319. #endregion
  320. #region 检查Cookie集合中是否包含指定的Cookie值
  321. /// <summary>
  322. /// 检查Cookie集合中是否包含指定的Cookie值
  323. /// </summary>
  324. /// <param name="cks">Cookie集合</param>
  325. /// <param name="ck">待判断的Cookie</param>
  326. /// <returns>Cookie集合中是否包含指定的Cookie</returns>
  327. public static async Task<bool> IncludeCKAsync(this List<string> cks, string ck)
  328. {
  329. try
  330. {
  331. return await Task.Run(() =>
  332. {
  333. foreach (string t in cks)
  334. {
  335. if (t.ToLower().Trim().IndexOf(ck.Remove(ck.IndexOf('=') + 1).Trim().ToLower(), StringComparison.Ordinal) != -1)
  336. {
  337. return true;
  338. }
  339. }
  340. return false;
  341. }).ConfigureAwait(false);
  342. }
  343. catch (Exception)
  344. {
  345. return false;
  346. }
  347. }
  348. #endregion
  349. #region 设置系统Cookie
  350. /// <summary>
  351. /// 设置系统Cookie
  352. /// </summary>
  353. /// <param name="lpszUrlName">Cookie域</param>
  354. /// <param name="lbszCookieName">Cookie名</param>
  355. /// <param name="lpszCookieData">Cookie数据</param>
  356. /// <returns>设置成功与否</returns>
  357. [System.Runtime.InteropServices.DllImport("wininet.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto, SetLastError = true)]
  358. public static extern bool InternetSetCookie(string lpszUrlName, string lbszCookieName, string lpszCookieData);
  359. #endregion
  360. #region 获取所有可能的Cookie域
  361. /// <summary>
  362. /// 获取所有可能的Cookie域
  363. /// </summary>
  364. /// <param name="url">域的全称</param>
  365. /// <returns>所有可能的域</returns>
  366. public static List<string> GetDomains(string url)
  367. {
  368. List<string> res = new List<string>();
  369. try
  370. {
  371. url = url.Remove(url.IndexOf("?"));
  372. }
  373. catch (Exception e)
  374. {
  375. LogManager.Error(e);
  376. }
  377. try
  378. {
  379. Uri uri = new Uri(url);
  380. string baseDomain = uri.Scheme + "://" + uri.Host;
  381. for (int i = 0; i < uri.Segments.Length; i++)
  382. {
  383. baseDomain += uri.Segments[i];
  384. res.Add(baseDomain);
  385. }
  386. }
  387. catch (Exception e)
  388. {
  389. LogManager.Error(e);
  390. }
  391. return res;
  392. }
  393. #endregion
  394. #region 将Cookie字符串描述的Cookie追加到CookieCoollection
  395. /// <summary>
  396. /// 将Cookie字符串描述的Cookie追加到CookieCoollection
  397. /// </summary>
  398. /// <param name="cc">CookieCoollection</param>
  399. /// <param name="ck">Cookie字符串</param>
  400. /// <param name="url">Cookie的域</param>
  401. public static void SetCKAppendToCC(this CookieCollection cc, string ck, string url)
  402. {
  403. CookieCollection tmp = GetCK(ck, url);
  404. for (int i = 0; i < tmp.Count; i++)
  405. {
  406. cc.Add(tmp[i]);
  407. }
  408. }
  409. #endregion
  410. #region 将Cookie字符串设置到系统中,便于浏览器使用
  411. /// <summary>
  412. /// 将Cookie字符串设置到系统中,便于浏览器使用
  413. /// </summary>
  414. /// <param name="ck">Cookie字符串</param>
  415. /// <param name="url">Cookie的域</param>
  416. public static void SetCKToSystem(string ck, string url)
  417. {
  418. string[] cks = GetCKS(ck);
  419. for (int i = 0; i < cks.Length; i++)
  420. {
  421. string[] nv = cks[i].Split('=');
  422. InternetSetCookie(url, nv[0], nv.Length > 1 ? nv[1] : "");
  423. }
  424. }
  425. #endregion
  426. #region 将CookieCollection中的Cookie设置到系统中,便于浏览器使用
  427. /// <summary>
  428. /// 将CookieCollection中的Cookie设置到系统中,便于浏览器使用
  429. /// </summary>
  430. /// <param name="cc">CookieCollection</param>
  431. /// <param name="url">Cookie的域</param>
  432. public static void SetCKToSystem(this CookieCollection cc, string url)
  433. {
  434. List<string> domains = GetDomains(url);
  435. for (int i = 0; i < cc.Count; i++)
  436. {
  437. for (int j = 0; j < domains.Count; j++)
  438. {
  439. InternetSetCookie(domains[j], cc[i].Name, cc[i].Value);
  440. }
  441. }
  442. }
  443. #endregion
  444. /// <summary>
  445. /// 格式化Cookie为标准格式
  446. /// </summary>
  447. /// <param name="key">Key值</param>
  448. /// <param name="value">Value值</param>
  449. /// <returns>格式化后的数据</returns>
  450. public static string CookieFormat(string key, string value)
  451. {
  452. return string.Format("{0}={1};", key, value);
  453. }
  454. }
  455. /// <summary>
  456. /// Cookie对象
  457. /// </summary>
  458. public class CookieItem
  459. {
  460. /// <summary>
  461. /// 键
  462. /// </summary>
  463. public string Key { get; set; }
  464. /// <summary>
  465. /// 值
  466. /// </summary>
  467. public string Value { get; set; }
  468. }
  469. }