如何从 HttpResponseMessage 获取 cookie?
执行以下代码时出现索引越界异常。不知道问题出在哪里:
using System;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
namespace ConsoleApp1
{
internal class Program
{
static HttpClientHandler handler = new HttpClientHandler();
static HttpClient client = new HttpClient(handler);
static async Task Main(string[] args)
{
Console.WriteLine("Hello, World!");
await ReadCookies();
Thread.Sleep(15000);
}
static async Task ReadCookies()
{
for (int i = 0; i < 10; i++)
{
client.BaseAddress = new Uri("http://google.com");
var request = new HttpRequestMessage(HttpMethod.Get, "index.html");
var response = await client.SendAsync(request);
var cks = GetCookies(response);
Console.WriteLine(await response.Content.ReadAsStringAsync());
Thread.Sleep(1000);
foreach (Cookie ck in cks)
{
Console.WriteLine($"{ck.Name}:{ck.Value}");
}
}
}
static CookieCollection GetCookies(HttpResponseMessage message)
{
var cookies = new CookieCollection();
var setCookie = Enumerable.Empty<string>();
if (message.Headers.TryGetValues("Set-Cookie", out setCookie))
{
foreach (var cookieStr in setCookie)
{
foreach (var cookieToken in cookieStr.Split(';'))
{
var keyValueTokens = cookieToken.Split('=');
var cookie = new Cookie((keyValueTokens[0]).Trim(), (keyValueTokens[1]).Trim());
cookies.Add(cookie);
}
}
}
return cookies;
}
}
}
这应该可以解决大多数边缘情况:
public static CookieCollection GetCookies(HttpResponseMessage message)
{
var cookies = new CookieCollection();
if (message == null)
return cookies;
var setCookie = Enumerable.Empty<string>();
if (message.Headers.TryGetValues("Set-Cookie", out setCookie))
{
foreach (var cookieStr in setCookie)
{
foreach (var cookieToken in cookieStr.Split(';'))
{
var name = cookieToken.Trim();
var value = "";
if (cookieToken.Contains('='))
{
var keyValueTokens = cookieToken.Split('=');
name = (keyValueTokens[0]).Trim();
if (keyValueTokens.Length > 1 && !string.IsNullOrEmpty(keyValueTokens[1]))
{
value = (keyValueTokens[1]).Trim();
}
}
if (!string.IsNullOrEmpty(name))
{
var cookie = new Cookie(name, value);
cookies.Add(cookie);
}
}
}
}
return cookies;
}
改进Dan的代码,将cookie属性正确添加到cookie对象中,同时也解决了cookie中存在多个token时的问题;就像你也有一个“refreshToken”一样。
public static CookieCollection GetCookies(HttpResponseMessage message)
{
var cookies = new CookieCollection();
if (message == null)
return cookies;
var setCookie = Enumerable.Empty<string>();
if (message.Headers.TryGetValues("Set-Cookie", out setCookie))
{
foreach (var cookieStr in setCookie)
{
Cookie cookie = null;
foreach (var cookieToken in cookieStr.Split(';'))
{
if (cookieToken.Contains('='))
{
var keyValueTokens = cookieToken.Split('=');
var name = (keyValueTokens[0]).Trim();
var value = "";
if (keyValueTokens.Length > 1 && !string.IsNullOrEmpty(keyValueTokens[1]))
value = (keyValueTokens[1]).Trim();
if (cookie == null)
{
cookie = new Cookie(name, value);
continue;
}
switch (name)
{
case "Path":
cookie.Path = value;
break;
case "Expires":
cookie.Expires = DateTime.Parse(value);
break;
case "HttpOnly":
cookie.HttpOnly = true;
break;
case "Secure":
cookie.Secure = true;
break;
}
}
cookies.Add(cookie);
}
}
}
return cookies;
}