-
C#中关于HTTP/HTTPS协议(请求/响应头、状态码、RESTful API)
第5章 HTTP/HTTPS协议深度解析
5.1 HTTP/HTTPS协议(请求/响应头、状态码、RESTful API)
一、为什么要学HTTP/HTTPS?
我刚学C#时,以为HTTP就是“浏览器访问网页”,直到做后端接口开发,才发现HTTP是所有网络应用的“通用语言”——不管是网页、APP、小程序,还是物联网设备,都是用HTTP/HTTPS通信。现在我做的项目,90%以上的接口都是HTTP接口。这节我把自己做接口开发时踩过的坑、常用的技巧都揉进去,用大白话讲透HTTP的核心知vb.net教程C#教程python教程SQL教程access 2010教程识点,结合C#实战代码,让你既能看懂HTTP请求,又能自己写HTTP服务器和客户端。
二、先搞懂HTTP的本质:请求-响应模型
HTTP是无状态、无连接的应用层协议,核心是“请求-响应”模型:
1.客户端(浏览器、APP)发送一个HTTP请求给服务器;
2.服务器处理请求,返回一个HTTP响应给客户端;
3.一次请求-响应完成后,连接就断开(HTTP/1.1默认是长连接,但本质还是无状态)。
类比:HTTP就像你去餐馆吃饭——你点单(请求),厨师做饭(处理),服务员上菜(响应),吃完就走(断开连接),餐馆不会记住你上次点了什么(无状态)。
三、HTTP请求:客户端说什么?
一个完整的HTTP请求由3部分组成:请求行、请求头、请求体。
-
请求行:告诉服务器“我要做什么”
格式:请求方法 URL 协议版本
请求方法:常用的有GET、POST、PUT、DELETE(对应RESTful API的增删改查);
URL:要访问的资源地址(比如https://api.example.com/users/1);
协议版本:比如HTTP/1.1、HTTP/2、HTTP/3。
示例:GET /users/1 HTTP/1.1——用HTTP/1.1协议,请求获取ID为1的用户信息。 -
请求头:告诉服务器“我是谁、我要什么格式”
请求头是键值对,常用的请求头:
| 请求头 | 用途 |
|---|---|
| Host | 服务器的域名(比如api.example.com) |
| User-Agent | 客户端的身份(比如Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36) |
| Accept | 客户端能接受的响应格式(比如application/json) |
| Content-Type | 请求体的格式(比如application/json、application/x-www-form-urlencoded) |
| Authorization | 身份验证(比如Bearer token) |
| Cookie | 客户端的Cookie(用于会话保持) |
-
请求体:告诉服务器“具体数据是什么”
只有POST、PUT等方法才有请求体,常用的格式:
application/json:JSON格式(最常用,比如{"name":"张三","age":20});
application/x-www-form-urlencoded:表单格式(比如name=张三&age=20);
multipart/form-data:文件上传格式(比如上传图片、视频)。
四、HTTP响应:服务器说什么?
一个完整的HTTP响应由3部分组成:状态行、响应头、响应体。 -
状态行:告诉客户端“请求结果怎么样”
格式:协议版本 状态码 状态描述
状态码:3位数字,分为5类:
o1xx:信息(比如100 Continue,表示客户端可以继续发送请求体);
o2xx:成功(比如200 OK、201 Created);
o3xx:重定向(比如301 Moved Permanently、302 Found);
o4xx:客户端错误(比如400 Bad Request、401 Unauthorized、404 Not Found);
o5xx:服务器错误(比如500 Internal Server Error、503 Service Unavailable)。
示例:HTTP/1.1 200 OK——用HTTP/1.1协议,请求成功。 -
响应头:告诉客户端“我返回的是什么、怎么处理”
常用的响应头:
| 响应头 | 用途 |
| ---- | ---- |
| Content-Type | 响应体的格式(比如application/json) |
| Content-Length | 响应体的长度(字节数) |
| Cache-Control | 缓存策略(比如max-age=3600,表示缓存1小时) |
| Set-Cookie | 设置客户端的Cookie(用于会话保持) |
| Access-Control-Allow-Origin | 跨域资源共享(CORS),允许哪些域名访问 | -
响应体:告诉客户端“具体结果是什么”
响应体是服务器返回的数据,格式和请求头的Accept一致——比如客户端请求application/json,服务器就返回JSON格式的数据。
五、C#实战:用HttpClient发送HTTP请求
HttpClient是.NET官方封装的HTTP客户端,简化了HTTP请求的开发——就像你用手机浏览器上网,不需要懂HTTP协议的细节,直接输入网址就行。 -
发送GET请求:获取数据
csharp
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;
namespace HttpClientGetDemo;
class Program
{
static async Task Main(string[] args)
{
// 1. 创建HttpClient实例:建议全局单例,不要每次请求都创建(会耗尽端口)
using var httpClient = new HttpClient();
try
{
// 2. 发送GET请求
string url = "https://jsonplaceholder.typicode.com/users/1";
HttpResponseMessage response = await httpClient.GetAsync(url);
// 3. 检查请求是否成功:如果状态码不是2xx,抛出异常
response.EnsureSuccessStatusCode();
// 4. 读取响应体:把JSON字符串转换成对象
string jsonString = await response.Content.ReadAsStringAsync();
User user = JsonSerializer.Deserialize<User>(jsonString) ?? new User();
// 5. 输出结果
Console.WriteLine($"用户ID:{user.Id}");
Console.WriteLine($"用户名:{user.Name}");
Console.WriteLine($"邮箱:{user.Email}");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"请求失败:{ex.Message}");
}
}
// 定义User类,和JSON格式对应
public class User
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
}
}
代码逐行讲:
1.using var httpClient = new HttpClient();:用using声明,自动释放HttpClient资源;注意:HttpClient是线程安全的,建议全局单例(比如用IHttpClientFactory),不要每次请求都创建,否则会耗尽系统端口;
2.await httpClient.GetAsync(url);:异步发送GET请求,返回HttpResponseMessage(包含响应状态码、响应头、响应体);
3.response.EnsureSuccessStatusCode();:如果状态码不是2xx,抛出HttpRequestException(比如404、500);
4.await response.Content.ReadAsStringAsync();:读取响应体的字符串内容;
5.JsonSerializer.Deserialize
2. 发送POST请求:提交数据
csharp
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
namespace HttpClientPostDemo;
class Program
{
static async Task Main(string[] args)
{
using var httpClient = new HttpClient();
try
{
// 1. 准备要提交的数据
var newUser = new User
{
Name = "张三",
Email = "zhangsan@example.com"
};
// 2. 发送POST请求:自动把对象转换成JSON,设置Content-Type为application/json
string url = "https://jsonplaceholder.typicode.com/users";
HttpResponseMessage response = await httpClient.PostAsJsonAsync(url, newUser);
response.EnsureSuccessStatusCode();
// 3. 读取响应体:获取创建后的用户信息
User createdUser = await response.Content.ReadFromJsonAsync<User>() ?? new User();
Console.WriteLine($"创建的用户ID:{createdUser.Id}");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"请求失败:{ex.Message}");
}
}
public class User
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
}
}
代码关键:await httpClient.PostAsJsonAsync(url, newUser);——自动把newUser对象转换成JSON格式,设置Content-Type为application/json,简化了POST请求的开发。
3. 发送PUT请求:更新数据
csharp
// 发送PUT请求:更新ID为1的用户信息
var updatedUser = new User
{
Id = 1,
Name = "李四",
Email = "lisi@example.com"
};
HttpResponseMessage response = await httpClient.PutAsJsonAsync("https://jsonplaceholder.typicode.com/users/1", updatedUser);
-
发送DELETE请求:删除数据
csharp
// 发送DELETE请求:删除ID为1的用户信息
HttpResponseMessage response = await httpClient.DeleteAsync("https://jsonplaceholder.typicode.com/users/1");
六、C#实战:用Kestrel写HTTP服务器
Kestrel是.NET官方的跨平台HTTP服务器,性能很高——ASP.NET Core就是基于Kestrel的。下面用Kestrel写一个简单的HTTP服务器,处理RESTful API请求。
-
安装依赖
在项目中安装Microsoft.AspNetCore.App包:
bash
dotnet add package Microsoft.AspNetCore.App -
编写HTTP服务器代码
csharp
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using System.Text.Json;
using System.Threading.Tasks;
namespace KestrelHttpServerDemo;
class Program
{
static async Task Main(string[] args)
{
// 1. 创建WebApplication实例:Kestrel的入口
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 2. 配置路由:处理RESTful API请求
app.MapGet("/users/{id:int}", async (int id, HttpContext context) =>
{
// 模拟从数据库获取用户信息
var user = new User { Id = id, Name = $"用户{id}", Email = $"user{id}@example.com" };
// 设置响应头:Content-Type为application/json
context.Response.ContentType = "application/json";
// 把用户对象转换成JSON,写入响应体
await JsonSerializer.SerializeAsync(context.Response.Body, user);
});
app.MapPost("/users", async (HttpContext context) =>
{
// 读取请求体:把JSON转换成User对象
User? newUser = await JsonSerializer.DeserializeAsync<User>(context.Request.Body);
if (newUser == null)
{
// 返回400错误:请求体格式错误
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync("请求体格式错误");
return;
}
// 模拟保存到数据库,生成ID
newUser.Id = 100;
// 返回201状态码:创建成功,返回创建后的用户信息
context.Response.StatusCode = StatusCodes.Status201Created;
context.Response.ContentType = "application/json";
await JsonSerializer.SerializeAsync(context.Response.Body, newUser);
});
// 3. 启动服务器,监听5000端口
await app.RunAsync("http://localhost:5000");
}
public class User
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
}
}
代码逐行讲:
1.var builder = WebApplication.CreateBuilder(args);:创建WebApplication实例,自动配置Kestrel服务器;
2.app.MapGet("/users/{id:int}", async (int id, HttpContext context) => { ... });:配置GET路由,处理/users/{id}请求,{id:int}表示ID是整数;
3.context.Response.ContentType = "application/json";:设置响应头的Content-Type为application/json,告诉客户端返回的是JSON格式;
4.await JsonSerializer.SerializeAsync(context.Response.Body, user);:把user对象转换成JSON,写入响应体;
5.context.Response.StatusCode = StatusCodes.Status201Created;:返回201状态码,表示资源创建成功;
6.await app.RunAsync("http://localhost:5000");:启动服务器,监听5000端口。
3. 测试服务器
用Postman或curl测试:
GET请求:curl http://localhost:5000/users/1——返回{"Id":1,"Name":"用户1","Email":"user1@example.com"};
POST请求:curl -X POST -H "Content-Type: application/json" -d '{"Name":"张三","Email":"zhangsan@example.com"}' http://localhost:5000/users——返回{"Id":100,"Name":"张三","Email":"zhangsan@example.com"},状态码201。
七、RESTful API:HTTP请求的“最佳实践”
RESTful API是一种HTTP API的设计风格,核心是“资源”:
用URL表示资源(比如/users表示所有用户,/users/1表示ID为1的用户);
用HTTP方法表示对资源的操作:
oGET:获取资源(比如GET /users/1获取ID为1的用户);
oPOST:创建资源(比如POST /users创建新用户);
oPUT:更新资源(比如PUT /users/1更新ID为1的用户);
oDELETE:删除资源(比如DELETE /users/1删除ID为1的用户)。
RESTful API示例:
| HTTP方法 | URL | 用途 |
|---|---|---|
| GET | /users | 获取所有用户 |
| GET | /users/1 | 获取ID为1的用户 |
| POST | /users | 创建新用户 |
| PUT | /users/1 | 更新ID为1的用户 |
| DELETE | /users/1 | 删除ID为1的用户 |
八、HTTPS:HTTP的“安全版”
HTTPS是HTTP + SSL/TLS,核心是加密传输,防止数据被窃听、篡改、伪造。
-
HTTPS的核心流程:握手、加密传输
1.客户端向服务器发送HTTPS请求,服务器返回SSL证书;
2.客户端验证证书的合法性(比如是否由可信CA颁发、是否过期);
3.客户端和服务器协商加密算法,生成会话密钥;
4.后续的HTTP请求和响应都用会话密钥加密传输。
类比:HTTPS就像你用加密的信封寄信——信封上有锁(SSL证书),只有收件人有钥匙(服务器的私钥),中间的人打不开信封(无法窃听、篡改)。 -
C#实战:用HttpClient发送HTTPS请求
HttpClient自动支持HTTPS,不需要额外配置——只要URL是https://开头就行:
csharp
using var httpClient = new HttpClient();
string url = "https://api.example.com/users/1";
HttpResponseMessage response = await httpClient.GetAsync(url);
注意:如果服务器用的是自签名证书(比如测试环境),HttpClient会验证失败,需要跳过证书验证(生产环境不要这么做):
csharp
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
using var httpClient = new HttpClient(handler);
九、基础知识拓展
-
什么是HTTP/2?比HTTP/1.1好在哪?
HTTP/2是HTTP/1.1的升级版,核心改进:
多路复用:一个连接可以传输多个流,不会互相阻塞(HTTP/1.1一个连接一次只能传输一个请求);
二进制分帧:把HTTP请求和响应分成二进制帧,传输效率更高;
服务器推送:服务器可以主动把资源推送给客户端(比如客户端请求HTML,服务器主动推送CSS、JS)。
性能提升:HTTP/2的吞吐量比HTTP/1.1高2~3倍,延迟更低——现在大部分浏览器和服务器都支持HTTP/2。 -
什么是CORS?跨域请求怎么解决?
CORS(跨域资源共享)是浏览器的安全策略——默认不允许从一个域名的网页请求另一个域名的API(比如http://localhost:3000的网页请求http://localhost:5000的API)。
解决方法:在服务器端设置Access-Control-Allow-Origin响应头,允许指定域名访问:
csharp
// Kestrel服务器允许所有域名访问
app.UseCors(policy => policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
-
什么是OAuth2.0?身份验证的“标准流程”
OAuth2.0是一种身份验证协议,用于第三方应用获取用户的授权(比如微信登录、GitHub登录)。核心流程:
1.第三方应用引导用户到授权服务器(比如微信);
2.用户登录并授权第三方应用;
3.授权服务器返回授权码给第三方应用;
4.第三方应用用授权码换访问令牌;
5.第三方应用用访问令牌访问用户的资源(比如获取用户的基本信息)。
C#实战:用Microsoft.Identity.Web库实现OAuth2.0登录:
csharp
// 安装依赖:Install-Package Microsoft.Identity.Web
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
十、总结:HTTP/HTTPS是网络编程的“通用语言”
HTTP:无状态、无连接的请求-响应协议,适合大部分网络应用;
HTTPS:HTTP + SSL/TLS,加密传输,适合需要安全的场景(比如支付、登录);
RESTful API:HTTP API的最佳实践,用URL表示资源,用HTTP方法表示操作;
HttpClient:.NET官方的HTTP客户端,简化了HTTP请求的开发;
Kestrel:.NET官方的HTTP服务器,性能很高,适合开发ASP.NET Core应用。
本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49518.html










