HTTP 快速解析

一、HTTP请求结构

HTTP请求和响应报文由以下部分组成(以请求报文为例):

  • 请求报文结构:

    1. 请求行:包含HTTP方法(如GET/POST)、请求URL和协议版本(如HTTP/1.1,HTTP/2.0,HTTP/3.0),格式为 方法 URL 协议版本
    2. 请求头(Headers):包含元数据如 Host(目标域名)、Content-Length(报文主体长度)、Accept(客户端支持的数据格式)等。
    3. 空行:用于分隔请求头和报文主体。
    4. 报文主体:通常为请求参数(GET方法无主体)或JSON/表单数据(POST/PUT方法)。

    在这里插入图片描述

  • 响应报文结构:状态行(含状态码)、响应头、空行、响应主体。

    在这里插入图片描述


二、常用HTTP状态码分类

1. 1xx(信息性状态码)

  • 100 Continue:服务器已接收请求头,客户端可继续发送请求体。
  • 101 Switching Protocols:协议切换(如WebSocket)

2. 2xx(成功状态码)

  • 200 OK:请求成功,返回完整数据。
  • 204 No Content:请求成功但无返回数据(如DELETE操作)。
  • 206 Partial Content:返回部分资源(如断点续传)

3. 3xx(重定向状态码)

响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。

  • 301 Moved Permanently:资源永久迁移,搜索引擎需更新URL。
  • 304 Not Modified:客户端缓存有效,服务器不返回新内容。
  • 307 Temporary Redirect:临时重定向,保留原始请求方法(如POST)。
  • 302 Temporary Redirect:临时重定向,可能将POST转为GET。
  • 303 Temporary Redirect:临时重定向,强制转GET,如,POST后跳转到GET页面(如表单提交)。

4. 4xx(客户端错误)

  • 400 Bad Request:请求语法错误。
  • 403 Forbidden:服务器拒绝请求(权限不足)。
  • 404 Not Found:资源不存在。
  • 416 Requested Range Not Satisfiable:断点下载时客户端头range 超过资源大小。

5. 5xx(服务器错误)

  • 500 Internal Server Error:服务器内部错误。
  • 503 Service Unavailable:服务器过载或维护。
  • 502 BadGateway:作为网关或者代理工作的服务器(如Nginx)尝试执行请求时,从上游服务器接收到无效的响应。
  • 504 GatewayTime-out:作为网关或者代理工作的服务器(如Nginx)尝试执行请求时,未能及时从上游服务器收到响应。

三、状态码使用场景

1. 206 Partial Content

  • 场景:客户端通过 Range 头请求资源的某部分(如大文件分块下载或视频流播放)。
  • 示例:
    GET /large-file.mp4 HTTP/1.1
    Range: bytes=0-999
    
    服务器返回 206 Partial Content 和对应数据块。

2. 304 Not Modified

  • 场景:客户端携带 If-Modified-Since(最后修改时间)或 If-None-Match(ETag)请求资源,服务器验证后确认未修改。
  • 流程:
    1. 客户端首次请求,服务器返回资源及 Last-ModifiedETag
    2. 客户端再次请求时携带上述字段,服务器返回 304,客户端使用本地缓存。

小结

206 用于分块传输,304 用于缓存优化,两者均减少网络传输量。


四、HTTP缓存机制

1. 强制缓存

  • 原理:客户端直接使用本地缓存,无需请求服务器。
  • 控制字段:
    • Cache-Control: max-age=3600(缓存3600秒)。
    • Expire: Wed, 20 Jan 2026 12:00:00 GMT(过期时间)。
  • Cache-Control 的优先级高于 Expires

2. 协商缓存

  • 原理:客户端与服务器协商是否使用缓存。
  • 实现方式:
    • Last-Modified:客户端发送 If-Modified-Since,服务器比对时间。
    • ETag:客户端发送 If-None-Match,服务器校验资源哈希值。
  • 优先级:ETag > Last-Modified(更精确)。

    Last-Modified基于时间实现,ETag是基于唯一标识实现,故而ETag可以避免由于时间篡改导致的不可信问题。

  • 304 Not Modified:客户端缓存有效,服务器不返回新内容。
  • 使用时与强制缓存配合使用,只有强制缓存失效才会使用协商缓存。

3. 缓存失效

  • 主动失效:服务器通过 Cache-Control: no-cacheCache-Control: no-store 强制客户端重新请求。
  • 被动失效:资源更新后,客户端下次请求会触发重新校验。

小结

HTTP缓存通过强制和协商机制提升性能,开发者需根据场景选择合适策略(如静态资源用强制缓存,动态内容用协商缓存)。


五、应用

基于 Java 原生 HttpURLConnection 的文件下载:

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;public class FileDownloadExample {public static void main(String[] args) {URL url = new URL("https://blog.csdn.net/xiaolingting?type=blog");HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();urlConnection.setRequestMethod("GET");urlConnection.setConnectTimeout(5000);urlConnection.setReadTimeout(10000);int responseCode = urlConnection.getResponseCode();if (responseCode != HttpURLConnection.HTTP_OK) {System.out.println("download error");return;}
// 1.0 传统方式   try (InputStream inputStream = urlConnection.getInputStream();FileOutputStream download = new FileOutputStream("download");) {BufferedInputStream bis = new BufferedInputStream(inputStream);BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(download);int bytesRead = 0;byte[] buffer = new byte[4 * 1024];while ((bytesRead = bis.read(buffer))  != -1) {bufferedOutputStream.write(buffer, 0, bytesRead);}} catch (IOException e) {throw new RuntimeException(e);}// 2.0 NIO 优化
// 		try(InputStream inputStream = urlConnection.getInputStream();
//            FileChannel download = FileChannel.open(Paths.get("download"),
//                    StandardOpenOption.CREATE, StandardOpenOption.WRITE,StandardOpenOption.READ)) {
//
//            MappedByteBuffer mapBuffer = download.map(FileChannel.MapMode.READ_WRITE, 0,
//                    urlConnection.getContentLength());
//
//            int bytesRead = 0;
//            byte[] buffer = new byte[4 * 1024];
//            while ((bytesRead = inputStream.read(buffer))  != -1) {
//                mapBuffer.put(buffer, 0, bytesRead);
//            }
//
//
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }        urlConnection.disconnect();}
}

代码说明

  1. HTTP 连接建立

    • 使用 HttpURLConnection 建立与目标 URL 的连接,设置超时时间避免阻塞。
  2. 响应码检查

    • 通过 connection.getResponseCode() 获取响应码,仅当状态码为 200 OK 时继续下载。
  3. 流处理

    • 输入流:通过 connection.getInputStream() 获取服务器返回的字节流。
    • 缓冲流:使用 BufferedInputStreamBufferedOutputStream 提升读写效率。
    • 分块读取:通过 4KB 缓冲区循环读取数据,避免大文件内存溢出。
  4. 异常处理

    • 使用 try-with-resources 自动关闭流,防止资源泄漏。
    • 捕获 IOException 处理网络或IO错误。

扩展功能

  1. 断点续传
    添加 Range 请求头指定下载范围:

    connection.setRequestProperty("Range", "bytes=0-");
    

    处理 206 Partial Content 状态码。

    if (responseCode == HttpURLConnection.HTTP_PARTIAL) { // 206 Partial Content//  获取输入流并计算总文件大小try (InputStream inputStream = connection.getInputStream;RandomAccessFile file = new RandomAccessFile(savePath, "rw")) {// 跳过已下载的字节位置file.seek(file.length);byte[] buffer = new byte[4 * 1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {file.write(buffer, 0, bytesRead);downloadedBytes += bytesRead;updateCheckpoint(checkpointFile, downloadedBytes); // 更新断点记录}}
    }
    • 请求头:
      • Range头格式:Range: bytes=START-END,支持灵活范围(如bytes=-500表示最后500字节)。
    • 响应头:
      • Content-Range: bytes START-END/TOTAL:指示返回的字节范围及文件总大小。
      • Content-Length:当前片段的长度。
      • Accept-Ranges: bytes 或 Accept-Ranges: none。
  2. 进度监控
    while 循环中累加已读字节数,结合总文件大小(从 Content-Length 头获取)计算下载进度。

  3. MD5 校验
    添加 ETagLast-Modified 头验证文件一致性。


注意事项

  • HTTPS 支持:需处理证书问题(默认信任所有证书可能不安全),参考HTTPS实现安全的关键方法及技术细节。
  • 大文件下载:建议使用 NIO 或异步流提升性能。
  • 生产环境:推荐使用 Apache HttpClient 或 OkHttp 等成熟库。

六、其它细节

1、HTTP版本差异

  • HTTP/1.1使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。

    HTTP的Keep-Alive,可以使用同一个TCP连接来发送和接收多个HTTP请求/应答,避免了连接建立和释放的开销,这就是HTTP长连接。

  • HTTP/2.0 协议是基于 HTTPS 的,即 HTTP/2.0 是安全的。

    • HTTP 默认端口号是 80,HTTPS 默认端口号是 443。
    • HTTP/2 .0 相比 HTTP/1.1 性能上的改进:
      • 头部压缩:采用 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,后续请求不必发送相同字段,只发送索引号,这样就提高速度了。
      • 二进制格式:头信息和数据体都是二进制,并且统称为帧(frame):头信息帧(HeadersFrame)和数据帧(DataFrame)。服务端可以直接解析二进制报文,这增加了数据传输的效率。
      • 并发传输:单个TCP连接可并行传输多个请求/响应,通过数据流(Stream)标识区分不同请求,彻底解决队头阻塞。
      • 服务器主动推送资源:HTTP/2还在一定程度上改善了传统的「请求-应答」工作模式,服务端不再是被动地响应,可以主动向客户端发送消息。服务器可预判客户端需求,主动推送资源(如CSS/JS文件),减少往返次数。
  • HTTP/1.1 和 HTTP/2.0 传输协议使用的是 TCP 协议,而到了 HTTP/3.0 传输协议改用了 UDP 协议。

关于HTTPS细节可以参考HTTPS实现安全的关键方法及技术细节

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

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

相关文章

【AI学习】李宏毅新课《DeepSeek-R1 这类大语言模型是如何进行「深度思考」(Reasoning)的?》的部分纪要

针对推理模型,主要讲了四种方法,两种不需要训练模型,两种需要。 对于reason和inference,这两个词有不同的含义! 推理时计算不是新鲜事,AlphaGo就是如此。 这张图片说明了将训练和推理时计算综合考虑的关系&…

Kotlin Flow流

一 Kotlin Flow 中的 stateIn 和 shareIn 一、简单比喻理解 想象一个水龙头(数据源)和几个水杯(数据接收者): 普通 Flow(冷流):每个水杯来接水时,都要重新打开水龙头从…

【嵌入式Linux】基于ARM-Linux的zero2平台的智慧楼宇管理系统项目

目录 1. 需求及项目准备(此项目对于虚拟机和香橙派的配置基于上一个垃圾分类项目,如初次开发,两个平台的环境变量,阿里云接入,摄像头配置可参考垃圾分类项目)1.1 系统框图1.2 硬件接线1.3 语音模块配置1.4 …

Linux运维中常用的磁盘监控方式

在Linux运维中,磁盘监控是一项关键任务,因为它能帮助我们预防磁盘空间不足或性能问题导致的服务中断或数据丢失。让我们来看看有哪些常用的磁盘监控方法吧! 1. 查看磁盘使用情况(df命令) df命令用于显示文件系统的…

OpenCV第6课 图像处理之几何变换(缩放)

1.简述 图像几何变换又称为图像空间变换,它将一幅图像中的坐标位置映射到另一幅图像中的新坐标位置。几何变换并不改变图像的像素值,只是在图像平面上进行像素的重新安排。 根据OpenCV函数的不同,本节课将映射关系划分为缩放、翻转、仿射变换、透视等。 2.缩放 2.1 函数…

(35)VTK C++开发示例 ---将图片映射到平面2

文章目录 1. 概述2. CMake链接VTK3. main.cpp文件4. 演示效果 更多精彩内容👉内容导航 👈👉VTK开发 👈 1. 概述 与上一个示例不同的是,使用vtkImageReader2Factory根据文件扩展名或内容自动创建对应的图像文件读取器&a…

【模型量化】量化基础

目录 一、认识量化 二、量化基础原理 2.1 对称量化和非对称量化 2.1.1 对称量化 2.1.2 非对称量化 2.1.3 量化后的矩阵乘 2.2 神经网络量化 2.2.1 动态量化 2.2.2 静态量化 2.3 量化感知训练 一、认识量化 量化的主要目的是节约显存、提高计算效率以及加快通信 dee…

【零基础入门】一篇掌握Python中的字典(创建、访问、修改、字典方法)【详细版】

🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀《PyTorch科研加速指南:即插即用式模块开发》-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. 字典 2.1 字典的创建 2.1.1 大括号+直接赋值 2.1.2 大括号…

PHP-session

PHP中,session(会话)是一种在服务器上存储用户数据的方法,这些数据可以在多个页面请求或访问之间保持。Session提供了一种方式来跟踪用户状态,比如登录信息、购物车内容等。当用户首次访问网站时,服务器会创…

第 5 篇:红黑树:工程实践中的平衡大师

上一篇我们探讨了为何有序表需要“平衡”机制来保证 O(log N) 的稳定性能。现在,我们要认识一位在实际工程中应用最广泛、久经考验的“平衡大师”——红黑树 (Red-Black Tree)。 如果你用过 Java 的 TreeMap​ 或 TreeSet​,或者 C STL 中的 map​ 或 s…

第十六届蓝桥杯 2025 C/C++组 客流量上限

目录 题目: 题目描述: 题目链接: 思路: 打表找规律: 核心思路: 思路详解: 得到答案的方式: 按计算器: 暴力求解代码: 快速幂代码: 位运…

一天学完JDBC!!(万字总结)

文章目录 JDBC是什么 1、环境搭建 && 入门案例2、核心API理解①、注册驱动(Driver类)②、Connection③、statement(sql注入)④、PreparedStatement⑤、ResultSet 3、jdbc扩展(ORM、批量操作)①、实体类和ORM②、批量操作 4. 连接池①、常用连接池②、Durid连接池③、Hi…

从原理到实战讲解回归算法!!!

哈喽,大家好,我是我不是小upper, 今天系统梳理了线性回归的核心知识,从模型的基本原理、参数估计方法,到模型评估指标与实际应用场景,帮助大家深入理解这一经典的机器学习算法,助力数据分析与预测工作。 …

【dify—10】工作流实战——文生图工具

目录 一、创建工作流 应用 二、安装硅基流动 三、配置硅基流动 四、API测试 (1)进入API文档 (2)复制curl代码 (3)Postman测试API 五、 建立文生图工作流 (1)建立http请求 &…

Rust将结构导出到json如何处理小数点问题

简述 标准的 serde_json 序列化器不支持直接对浮点数进行格式化限制。如果将浮点数转换成字符串,又太low逼。这里重点推荐rust_decimal。 #[derive(Serialize)] pub struct StockTickRow {datetime: NaiveDateTime,code: String,name: String,#[serde(serialize_w…

openEuler 22.03 安装 Redis 6.2.9,支持离线安装

目录 一、环境检查1.1 必要环境检查1.2 在线安装(有网络)1.3 离线安装(无网络) 二、下载Redis2.1 在线下载2.2 离线下载 三、安装Redis四、配置Redis服务五、开机自启服务六、开放防火墙端口七、常用命令 一、环境检查 1.1 必要环…

MySQL基本查询(二)

文章目录 UpdateDelete插入查询结果(select insert)聚合函数分组聚合统计 Update 1. 语法: set后面加列属性或者表达式 UPDATE table_name SET column expr [, column expr …][WHERE …] [ORDER BY …] [LIMIT …] 案例 将孙悟空同学的…

Android Framework学习二:Activity创建及View绘制流程

文章目录 Window绘制流程Window Manager Service(WMS)SurfaceSurfaceFlinger 安卓View层次结构ActivityPhoneWindowActivity与PhoneWindow两者之间的关系ViewRootImplDecorViewDecorView 的作用DecorView 的结构总结 Activity创建流程View invalidate调用…

基于ssm的智慧养老平台(全套)

一、系统架构 前端:jsp | js | jquery | css 后端:spring | springmvc | mybatis 环境:jdk1.8 | mysql | maven | tomcat 二、代码及数据库 三、功能介绍 01. 登录 02. 管理员-主页 03. 管理员-个人中心 04. 管理员-…

计算机视觉技术的发展历程

计算机视觉技术的发展历程可以分为以下几个阶段: 早期探索阶段(1960s-1980s) 1960年代:计算机视觉的概念开始形成,研究者尝试让计算机识别和理解图像,主要集中在基础的图像处理,如边缘检测和特…