.Net HttpClient 使用 Cookie

news2025/5/19 20:26:13

在 HttpClient 中使用 Cookie

Cookie 是服务器存储在客户端的小型数据片段,可用于身份验证、会话跟踪等。

.Net HttpClient 支持 Cookie 功能,本教程详细介绍了Cookie 的管理与使用。

初始化

#!import "./Ini.ipynb"

什么是 Cookie

Cookie 是服务器发送到用户浏览器并存储在本地的一小段数据,用来进行会话管理(如登录状态)、个性化设置(如主题偏好)、跟踪用户行为等功能。

HttClient 手动管理 Cookie

如果只在简单的使用Cookie,想保持简洁、灵活。可以手管理。

发送带Cookie的请求

  • 不使用Cookie
{   //不使用Cookie
    using (var client = new HttpClient(){BaseAddress=new Uri(webApiBaseUrl)})
    {
        var response = await client.GetAsync("/api/Cookie/GetRequestCookie"); 

        //确保请求成功
        response.EnsureSuccessStatusCode();

        //读取响应内容
        var content = await response.Content.ReadAsStringAsync();

        //输出 响应内容
        Console.WriteLine(content);
    }
}
  • 手动设置Cookie: 在默认请求头中添加Cookie,适合快捷请求方法(Get,Post,Put,Delete等)
{   //多次请求时,都自动携带默认请求头Cookie

    var client = new HttpClient()
    {
        BaseAddress = new Uri(webApiBaseUrl),
    };

    //全局设置Cookie,所有快捷请求(Send方法的快捷方法:Get、Post、Put等)都会带上这个Cookie
    //快捷方法,不能单独设置Cookie; 只有Send方法才可以单独设置Cookie
    client.DefaultRequestHeaders.Add("Cookie", "Client=PolyglotNotebook,User=andy");

    //请求1
    var response = await client.GetAsync("/api/Cookie/GetRequestCookie"); 

    //确保请求成功
    response.EnsureSuccessStatusCode();

    //读取响应内容
    var content = await response.Content.ReadAsStringAsync();

    //输出 响应内容
    Console.WriteLine(content);

    //再次快捷请求,不用重新设置
    //请求2
    var response2 = await client.GetAsync("/api/Cookie/GetRequestCookie"); 

    //确保请求成功
    response2.EnsureSuccessStatusCode();

    //读取响应内容
    var content2 = await response2.Content.ReadAsStringAsync();

    //输出 响应内容
    Console.WriteLine(content2);

}
  • 手动设置Cookie:每次请求设置 HttpRequestMessage,适合Send通用方法。当然可以合并默认请求头
{   //手动设置Cookie, 单次HttpRequestMessage合并默认请求头Cookie

    var client = new HttpClient()
    {
        BaseAddress = new Uri(webApiBaseUrl),
    };

    //全局设置Cookie,所有请求都会带上这个Cookie
    client.DefaultRequestHeaders.Add("Cookie", "Client=PolyglotNotebook,User=andy");

    //单请求设置
    var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/Cookie/GetRequestCookie");
    
    //设置Cookie,会覆盖HttpClient设置的默认Cookie
    requestMessage.Headers.Add("Cookie", "Password=MyPassword,Role=Admin");
    //添加默认
    if(client.DefaultRequestHeaders.Contains("Cookie"))
    {
        requestMessage.Headers.Add("Cookie", client.DefaultRequestHeaders.GetValues("Cookie"));
    }

    var response = await client.SendAsync(requestMessage);
    var content = await response.Content.ReadAsStringAsync();
    Console.WriteLine(content);

    //响应头也会自动带上Cookie
    if(response.Headers.Contains("cookie"))
    {
        Console.Write($"响应头中Cookie为:");
        var cookies = response.Headers.GetValues("cookie");
        foreach (var cookie in cookies)
        {
            Console.WriteLine($"{cookie}");
        }
    }
    else
    {
        Console.WriteLine($"响应头中没有Cookie");
    }
}

查看响应头中的Cookie

{   //获取响应头中的Cookie

    var client = new HttpClient()
    {
        BaseAddress = new Uri(webApiBaseUrl),
    };

    var response = await client.GetAsync("/api/Cookie/GetResponseCookie");

    //获取响应头中的Cookie
    if(response.Headers.Contains("cookie"))
    {
        Console.Write($"响应头中Cookie为:");
        var cookies = response.Headers.GetValues("cookie");
        foreach (var cookie in cookies)
        {
            Console.WriteLine($"{cookie}");
        }
    }
    else
    {
        Console.WriteLine($"响应头中没有Cookie");
    }
}

HttClient 使用 CookieContainer 自动管理 Cookie

.NET 提供了 HttpClientHandler + CookieContainer 来自动管理 Cookie 生命周期和持久化。

使用 CookieContainer

{
    var handler = new HttpClientHandler()
    {
        UseCookies = true,
        CookieContainer = new CookieContainer(),
    };

    using var client = new HttpClient(handler)
    {
        BaseAddress = new Uri(webApiBaseUrl),
    };

    // 第一次请求,服务端设置 Cookie
    var response = await client.GetAsync("/api/Cookie/GetResponseCookie");
    response.EnsureSuccessStatusCode();

    // 第二次请求,自动携带之前设置的 Cookie
    var response2 = await client.GetAsync("/api/Cookie/GetRequestCookie");
    var content2 = await response2.Content.ReadAsStringAsync();
    Console.WriteLine(content2);
}

Cookie 持久化(保存与恢复)

若需要在程序重启后继续使用 Cookie,可将其序列化保存至文件或数据库。

  • 保存 Cookie 到文件
///<summary
/// 保存Cookie到文件
///</summary>
public void SaveCookies(CookieContainer container, string filePath)
{
    using (var writer = new StreamWriter(filePath))
    {
        foreach (Cookie cookie in container.GetCookies(new Uri(webApiBaseUrl)))
        {
            writer.WriteLine($"{cookie.Name}={cookie.Value};Domain={cookie.Domain};Path={cookie.Path};Expires={cookie.Expires}");
        }
    }
}

//应用
{
    var handler = new HttpClientHandler()
    {
        UseCookies = true,
        CookieContainer = new CookieContainer(),
    };

    using (var client = new HttpClient(handler))
    {
        client.BaseAddress = new Uri(webApiBaseUrl);

        // 第一次请求,服务端设置 Cookie
        var response = await client.GetAsync("/api/Cookie/GetResponseCookie");
        response.EnsureSuccessStatusCode();

        SaveCookies(handler.CookieContainer, "cookies.txt");
    }
}
  • 从文件中加载 Cookie
 <summary>
/// 从文件中加载 Cookie
/// </summary>
public CookieContainer LoadCookies(string filePath)
{
    var container = new CookieContainer();
    if (!File.Exists(filePath)) return container;

    foreach (var line in File.ReadAllLines(filePath))
    {
        var parts = line.Split(';');
        var nameValue = parts[0].Split('=');
        var cookie = new Cookie(nameValue[0], nameValue[1])
        {
            Domain = parts[1].Replace("Domain=", "").Trim(),
            Path = parts[2].Replace("Path=", "").Trim(),
            Expires = DateTime.Parse(parts[3].Replace("Expires=", "").Trim())
        };
        container.Add(cookie);
    }

    return container;
}

//发送请求:从文件中加载 Cookie, 在请求中携带
{
    var cookieBox = LoadCookies("cookies.txt");

    var handler = new HttpClientHandler()
    {
        UseCookies = true,
        CookieContainer = cookieBox,
    };

    var client = new HttpClient(handler)
    {
        BaseAddress = new Uri(webApiBaseUrl)
    };

    // 第一次请求,服务端设置 Cookie
    var response = await client.GetAsync("/api/Cookie/GetRequestCookie");
    response.EnsureSuccessStatusCode();

    var content = await response.Content.ReadAsStringAsync();

    Console.WriteLine(content);
}

跨域 Cookie 处理

默认情况下,CookieContainer 会根据域名自动隔离 Cookie。若需跨域共享 Cookie,可通过以下方式实现:

  • 手动复制 Cookie
//示例代码,无实际请求
var sourceUri = new Uri("https://source.com");
var targetUri = new Uri("https://target.com");

foreach (Cookie cookie in handler.CookieContainer.GetCookies(sourceUri))
{
    var crossDomainCookie = new Cookie(cookie.Name, cookie.Value, cookie.Path, targetUri.Host);
    handler.CookieContainer.Add(targetUri, crossDomainCookie);
}
  • 自定义 CookieContainer(高级)
    可以继承 CookieContainer 并重写相关方法以实现自定义 Cookie 共享策略。

进阶功能:Cookie 过期、安全标志、SameSite 设置等

  • 设置 Cookie 高级属性
{
    //发送请求
    {
        var handler = new HttpClientHandler()
        {
            UseCookies = true,
            CookieContainer = new CookieContainer(),
        };

        var client = new HttpClient(handler)
        {
            BaseAddress = new Uri(webApiBaseUrl)
        };

        //设置Cookie
        var cookie = new Cookie("jwt_token", "a.b.c")
        {
            Expires = DateTime.Now.AddDays(7),
            Domain = new Uri(webApiBaseUrl).Host,
            Path = "/",
            Secure = true,           // 仅 HTTPS 传输
            HttpOnly = true,         // 防止 XSS 攻击
        };

        handler.CookieContainer.Add(new Uri(webApiBaseUrl), cookie);

        // 第一次请求,服务端设置 Cookie
        var response = await client.GetAsync("/api/Cookie/GetRequestCookie");
        response.EnsureSuccessStatusCode();

        var content = await response.Content.ReadAsStringAsync();

        Console.WriteLine(content);
    }
}

总结

功能描述适用场景
手动设置 Cookie灵活、简单单次请求或固定 Cookie
使用 HttpRequestMessage更精细控制 Cookie 行为需要合并默认与自定义 Cookie
使用 CookieContainer自动管理 Cookie 生命周期多次请求、需要保持会话状态
Cookie 持久化保存 Cookie 至文件或数据库程序重启后仍需保持登录状态
跨域 Cookie手动复制或自定义容器需要在多个域名之间共享 Cookie
安全 Cookie 设置SecureHttpOnlySameSite增强 Cookie 安全性
获取 Cookie 属性查看 Cookie 的有效期、路径等信息调试和日志记录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2379513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GO语言语法---switch语句

文章目录 基本语法1. 特点1.1 不需要break1.2 表达式可以是任何类型1.3 省略比较表达式1.4 多值匹配1.5 类型switch1.6 case穿透1.7 switch后直接声明变量1.7.1 基本语法1.7.2 带比较表达式1.7.3 不带比较表达式1.7.4 结合类型判断 1.8 switch后的表达式必须与case语句中的表达…

开疆智能Profient转ModbusTCP网关连接ABB机器人MODBUS TCP通讯案例

本案例是通过开疆智能Profinet转ModbusTCP网关将西门子PLC与ABB机器人进行通讯 因西门子PLC采用Profinet协议&#xff0c;而ABB机器人采用的是ModbusTCP通讯。故采取此种方案。 配置过程&#xff1a; 1.MODBUS/TCP基于以太网&#xff0c;故ABB机器人在使用时需要有616-1PCIN…

解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

可以参考&#xff1a;解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed-CSDN博客 讲的是程序执行目录下可能缺少了&#xff1a; libssl-1_1-x64.dll 和 libcrypto-1_1-x64.dll 库文件&#xff0c;将其复制到可执行文件exe的同级目录下即可…

Text2SQL:自助式数据报表开发---0517

Text2SQL技术 早期阶段&#xff1a;依赖于人工编写的规则模板来匹配自然语言和SQL语句之间的对应关系 机器学习阶段&#xff1a;采用序列到序列模型等机器学习方法来学习自然语言与SQL之间的关系 LLM阶段&#xff1a;借助LLM强大的语言理解和代码生成能力&#xff0c;利用提示…

使用Visual Studio将C#程序发布为.exe文件

说明 .exe 是可执行文件&#xff08;Executable File&#xff09;的扩展名。这类文件包含计算机可以直接运行的机器代码指令&#xff0c;通常由编程语言&#xff08;如 C、C、C#、Python 等&#xff09;编译或打包生成。可以用于执行自动化操作&#xff08;执行脚本或批处理操…

React Flow 边的基础知识与示例:从基本属性到代码实例详解

本文为《React Agent&#xff1a;从零开始构建 AI 智能体》专栏系列文章。 专栏地址&#xff1a;https://blog.csdn.net/suiyingy/category_12933485.html。项目地址&#xff1a;https://gitee.com/fgai/react-agent&#xff08;含完整代码示​例与实战源&#xff09;。完整介绍…

oracle 资源管理器的使用

14.8.2资源管理器的使用 资源管理器控制CPU资源使用说明&#xff1a;  第一种分配方法&#xff1a;EMPHASIS CPU 分配方法确定在资源计划中对不同使用者组中的会话的重视程度。CPU占用率的分配级别为从1 到8&#xff0c;级别1 的优先级最高。百分比指定如何将CPU 资源分配给每…

贝叶斯优化Transformer融合支持向量机多变量回归预测,附相关性气泡图、散点密度图,Matlab实现

贝叶斯优化Transformer融合支持向量机多变量回归预测&#xff0c;附相关性气泡图、散点密度图&#xff0c;Matlab实现 目录 贝叶斯优化Transformer融合支持向量机多变量回归预测&#xff0c;附相关性气泡图、散点密度图&#xff0c;Matlab实现效果一览基本介绍程序设计参考资料…

Docker配置SRS服务器 ,ffmpeg使用rtmp协议推流+vlc拉流

目录 演示视频 前期配置 Docker配置 ffmpeg配置 vlc配置 下载并运行 SRS 服务 推拉流流程实现 演示视频 2025-05-18 21-48-01 前期配置 Docker配置 运行 SRS 建议使用 Docker 配置 Docker 请移步&#xff1a; 一篇就够&#xff01;Windows上Docker Desktop安装 汉化完整指…

一个stm32工程从底层上都需要由哪些文件构成

原文链接&#xff1a;https://kashima19960.github.io/2025/05/17/stm32/一个stm32工程从底层上都需要由哪些文件构成/ 前言 我最近因为做课设要用到stm32&#xff0c;所以去找了一些开源的stm32工程来看看&#xff0c;然后发现现在新版的keil mdk对于环境的配置跟以前 相比发…

[Mac] 开发环境部署工具ServBay 1.12.2

[Mac] 开发环境部署工具ServBay 链接&#xff1a;https://pan.xunlei.com/s/VOQS0LDsC_J6XU4p-R6voF6YA1?pwdnbyg# 非常给力的本地 Web 开发/测试环境工具&#xff1a;ServBay。之前我们本地搭个 PHP MySQL Nginx 环境&#xff0c;或者搞个 PHP web 环境啥的&#xff0c;不…

商城小程序源码介绍

今天要为大家介绍一款基于ThinkPHP、FastAdmin以及UniApp开发的商城小程序源码&#xff0c;这款源码在设计和功能上都有不俗的表现&#xff0c;非常适合想要搭建线上商城的开发者。 该源码采用了ThinkPHP作为后端框架&#xff0c;利用其强大的性能和灵活性&#xff0c;保障了系…

科技项目验收测试对软件产品和企业分别有哪些好处?

科技项目验收测试是指在项目的开发周期结束后&#xff0c;针对项目成果进行的一系列验证和确认活动。其目的是确保终交付的产品或系统符合预先设定的需求和标准。验收测试通常包括功能测试、性能测试、安全测试等多个方面&#xff0c;帮助企业评估软件在实际应用中的表现。 科…

汽车零部件冲压车间MES一体机解决方案

在当前制造业升级的大背景下&#xff0c;提升生产效率、实现精细化管理已成为企业竞争力的关键。特别是在汽车零部件制造领域&#xff0c;冲压车间作为生产流程中的重要一环&#xff0c;其生产数据的实时采集与分析对于确保产品质量、优化生产节拍、降低运营成本至关重要。今天…

hysAnalyser 从MPEG-TS导出ES功能说明

摘要 hysAnalyser 是一款特色的 MPEG-TS 数据分析工具。本文主要介绍了 hysAnalyser 从MPEG-TS 中导出选定的 ES 或 PES 功能(版本v1.0.003)&#xff0c;以便用户知悉和掌握这些功能&#xff0c;帮助分析和解决各种遇到ES或PES相关的实际问题。hysAnalyser 支持主流的MP1/MP2/…

家里wifi不能上网或莫名跳转到赌博及色情网站就是域名被劫持、DNS被污染了

文章目录 定义上网过程域名被劫持可能阶段案例排查工具 解决方法清除系统DNS缓存查看DNS缓存清除DNS缓存 登录路由器&#xff0c;设置DNS可用的DNS地址&#xff1a; 找网络运营商报警 定义 DNS&#xff08;Domain Name System&#xff0c;域名系统&#xff09;劫持&#xff0c…

基于SSM实现的健身房系统功能实现十六

一、前言介绍&#xff1a; 1.1 项目摘要 随着社会的快速发展和人们健康意识的不断提升&#xff0c;健身行业也在迅速扩展。越来越多的人加入到健身行列&#xff0c;健身房的数量也在不断增加。这种趋势使得健身房的管理变得越来越复杂&#xff0c;传统的手工或部分自动化的管…

【Java微服务组件】分布式协调P1-数据共享中心简单设计与实现

欢迎来到啾啾的博客&#x1f431;。 记录学习点滴。分享工作思考和实用技巧&#xff0c;偶尔也分享一些杂谈&#x1f4ac;。 欢迎评论交流&#xff0c;感谢您的阅读&#x1f604;。 目录 引言设计一个共享数据中心选择数据模型键值对设计 数据可靠性设计持久化快照 &#xff08…

cursor/vscode启动项目connect ETIMEDOUT 127.0.0.1:xx

现象&#xff1a; 上午正常使用cursor/vscode&#xff0c;因为需要写前端安装了nodejs16.20和vue2&#xff0c;结果下午启动前端服务无法访问&#xff0c;浏览器一直转圈。接着测试运行最简单的flask服务&#xff0c;vscode报错connect ETIMEDOUT 127.0.0.1:xx&#xff0c;要么…

兼顾长、短视频任务的无人机具身理解!AirVista-II:面向动态场景语义理解的无人机具身智能体系统

作者&#xff1a;Fei Lin 1 ^{1} 1, Yonglin Tian 2 ^{2} 2, Tengchao Zhang 1 ^{1} 1, Jun Huang 1 ^{1} 1, Sangtian Guan 1 ^{1} 1, and Fei-Yue Wang 2 , 1 ^{2,1} 2,1单位&#xff1a; 1 ^{1} 1澳门科技大学创新工程学院工程科学系&#xff0c; 2 ^{2} 2中科院自动化研究所…