如何使用HttpClient读取http标头并从HttpResponseMessage获取cookie

问题描述 投票:0回答:2

如何从 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;
        }
    }

}
c# .net cookies httpclient httpresponsemessage
2个回答
0
投票

这应该可以解决大多数边缘情况:

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;
    }

0
投票

改进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;
}
© www.soinside.com 2019 - 2024. All rights reserved.