网络原理--HTTP协议

news2025/3/5 11:03:46

http中文名为超文本传输协议,所谓“超文本”就是指传输范围超出了能在UTF8等码表上找到的字符的范围,包含一些图片,特殊格式之类的。

HTTP的发展简介

从图中可以看出到现在已经发展出了HTTP3,但是市面上的主流还是以HTTP1.0为主。

HTTP2.0和3.0都引入了很多新的特性,比如:提高传输效率,提高传输的安全性。而且在HTTP3.0以前,HTTP都是基于TCP实现的,而HTTP3.0则是基于UDP实现的。

HTTP的应用场景

HTTP协议主要应用于网站,如浏览器和服务器之间的数据传输,客户端(手机,PC)和服务器之间的数据传输。

HTTP协议的交互过程是什么典型的“一问一答”类型。

HTTP报文格式简介

要想了解HTTP的报文格式,就要借助抓包软件,这里使用fiddle抓包软件,在使用fiddle之前,我们要将其他代理软件也给关闭(例如翻墙软件),因为fiddle也是一个代理软件,代理软件之间会冲突,而且我们还要将HTTP协议的选项进行勾选,并且安装安全证书(会自动弹出)

在抓取的包中选取一个蓝色的(表示返回的是一个html,往往是返回一个网站的入口请求)。

右上角的请求明细

右下角的响应明细

在请求中我们选择“raw”显示请求的原始数据,然后选择“view in notepad”选择在记事本中打开即可。

http请求协议分为四个部分

1.首行

GET https://interface.bilibili.com/serverdate.js HTTP/1.1

其中首行又分为三个部分:1.“GET”:方法(method)。后面会仔细介绍。

2.“https://interface.bilibili.com/serverdate.js”:url(统一资源定位符)。使用空格分隔。

3.HTTP/1.1:版本号。

2.请求头(header)

从第二行一直到空行都是请求头。

3.空行

请求头下面会有一行空行,这个空行表示结束标记。

4.正文(body)

http的载荷部分,有的http请求有body,有的就没有(例如示例)。

http响应的基本格式

也是分为四个部分

1.首行

HTTP/1.1 200 OK

这里也是包含三个部分,三个部分之间使用空格进行分割。

1.HTTP/1.1:版本号。

2.200:状态码。

3.OK:状态码描述。

2.响应头   键值对

Date: Sun, 02 Mar 2025 13:08:24 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
york-server-zone: sh001
X-Cache-Webcdn: BYPASS from blzone03
Content-Length: 844
 

也就是从第二行开始,到空行截至。

3.空行

和请求报文相同,也是起到分割作用。

4.响应报文(body)载荷

<!--
BUILT_AT: 2024年12月12日 11:27
-->
<!doctype html><html lang="zh-CN"><head>
<!-- Dejavu Release Version 70436-->
<script>
window._BiliGreyResult = {
  method: "direct",
  versionId: "70436",
}
</script><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="renderer" content="webkit"/><title>header sync</title><meta name="theme-color" content="#4393E2"/><link rel="icon" href="//www.bilibili.com/favicon.ico"/><link rel="stylesheet" href="https://s1.hdslb.com/bfs/static/studio/static/cc-iconfont-2.11.0/iconfont.css"/></head><body><div id="app"></div><script src="//s1.hdslb.com/bfs/static/blive/blfe-message-navbar/static/js/vendors~b3ee6c4e.0377a2c3.js"></script><script src="//s1.hdslb.com/bfs/static/blive/blfe-message-navbar/static/js/header_sync.0377a2c3.js"></script></body></html>

响应的载荷是html,包含许多信息。

认识URL(统一资源定位符)

一个十分重要的概念,并不是只出现在HTTP协议中,JDBC中也会用到。

还有一个与url类似的概念:uri(唯一资源标识符),严格来说,uri比url的范围更加广一些。

例如: https://www.bilibili.com/   就是一个最简单的url,其中 https:// 表示协议的名称,www.bilibili.com/  则表示域名。

https://www.bilibili.com/video/BV1bKA8ewEQF/?spm_id_from=333.1007.tianma.1-3-3

也表示一个url(为了不让它成为一个链接,删除了部分信息),其中https://www.bilibili.com/video表示路径(带有层次结构)

而/BV1bKA8ewEQF/?spm_id_from=333.1007.tianma.1-3-3  表示查询字符串(query string),这里只有编写它的程序员才能看懂是什么意思。但是我们可以知道查询字符串使用键值对的形式,其中使用“&”来分割键值对,使用“=” 来分割键和值。

一个url的完整结构

1.关于登录信息:图中是不安全的写法,现在都是通过“单独的登录页面”来完成身份验证的。

2.服务器地址/域名:也可以是ip地址,后面带有端口号,表示你要访问服务器的哪一个端口。http默认端口为80,https为443。

3.带层次的文件路径:这里可能对于一个真实的硬盘文件,也可能对应一个虚拟的文件。

4.查询字符串:针对请求的内容做的补充说明。

5.片段标识符:用来表示当前页面的某个部分。通过不同的片段标识符可以完成页面内的跳转。

总结:访问网络上的资源:

1)通过ip地址知道服务器在哪。

2)通过端口号知道程序是哪个。

3)通过路径知道是访问哪个资源。

关于URL encode

query string里是自定应的键值对,在url中,本身有些特殊符号是有特殊含义的,例如:/,&,:,@ .......

如果url中的query string中也包含这些特殊符号怎么办?如果直接写进去,可能会使浏览器/服务器解析失败,靠谱的方法就是对上述符号进行转义。对于汉字也要进行转义。因为如果某个汉字的UTF8/gbk等编码值其中某个字节的编码中和某个符号的ascii值相同就麻烦了。

例如:GET https://ntp.msn.cn/edge/ntp?locale=zh-CN&title=%E6%96%B0%E5%BB%BA%E6%A0%87%E7%AD%BE%E9%A1%B5&dsp=1&sp=%E5%BF%85%E5%BA%94&prerender=1&PC=CNNDDB HTTP/1.1中就使用了大量的转义字符,例如:%E6%96%B0%E5%BB%BA%E6等。

在实际开发中,当要构造一个url时,当query string中包含中文或特殊符号时,一定要进行编码。

HTTP报文首行(方法,URL,版本号)

首行中的方法描述了这次请求是想干什么的。

HTTP提供一个标准文档(虽然是一厢情愿,很多程序员并不遵守)

最主要的方法是GET和POST,其他的方法使用的很少。

两个使用POST的典型场景:

1)登录。

2)上传。

一个实例:

body:{"username":"19308046376","password":"jJGHP1vwDm+ieEYaHl2Omg==","uuid":"456493d5f0fc4316b747208d88e6d7a0","status":0}

这里body使用的是json格式,密码则是使用base64进行了编码,base64特征是末尾带有“==”。base64有标准版(透明的,未进行加密),自定义版(自己约定编码规则,这时就可以作为一种加密手段)。

经典面试题:GET和POST有什么区别:

  首先总的来说,GET和POST没有本质上的区别,使用GET的场景也可以换成POST,使用POST的场景也可以换成GET。这取决于代码是咋写的,虽然在部分浏览器,部分服务器的某些特定情况下二者不可以替换,但是大部分情况下都是可以互换的。

但是GET和POST在使用习惯上还是有区别的:

1.GET习惯于把数据放到url的query string中,POST习惯于把数据放到body中。

2.语义上的区别。在标准文档中,GET是来获取数据的,POST是给服务器传输数据的。

3.关于幂等性(数学用语,每次输入情况一定,输出情况也一定,称为幂等;每次输入情况一定,输出情况不一定,不是幂等)。标准文档中,建议GET请求实现成幂等性,POST则无要求。

4.GET请求是可以被浏览器收藏夹收藏的,POST请求则不可以。

关于GET和POST某些不太准确的说法

1.POST比GET更加安全。论据:登录时,如果使用GET,用户名密码就会显示在url上,此时就会被人看到,所以不安全。

即使是POST,数据没有显示在url上,黑客也是可以通过抓包来获取到的,真正保证安全的关键在于加密,如果加密等级足够高,即使看见了也没什么关系。

2.GET传输的数据量小(存在上限),POST传输的数据量更大。

这种说法适用于以前,实际上HTTP的标准文档上说了,对于GET URL的长度不做限制,之前老版本的IE浏览器在实现时,URL的长度有限制,而目前则无限制了。

3.GET只能携带文本数据,POST则可以携带二进制数据。

这个说法并不是完全错误,只是有一定局限性。

URL通过query string来携带数据,query string是只能包含文本的,但是可以对二进制数据进行 urldecode,自然就成了文本了,到了服务器那边再进行 urldecode,就可以还原为二进制数据。

POST请求body中是可以携带二进制数据的,但是很多时候是对二进制数据进行urlencode/base64等方式转码。

请求头

1.Host

表示服务器主机的地址和端口,URL中已经有Host了,二者在绝大部分情况下是一样的,少数情况下可能不同。

2.Content-Length

表示body中的数据长度。通过这个长度来明确包之间的界限,处理粘包问题,因为HTTP也是基于TCP实现的,也会存在粘包问题。

3.Content-Type

表示请求的body中的数据格式。body中可以传输很多种格式的,包括程序员也可以自己约定任意的格式,但是有些格式是很常见的:

请求中

1)applicaton/json

2)application/x-www-urlencoded(称为form表单,通过html中的form标签构造出来的一种格式,特点是认为把query string放入到body中了。

响应中

1)text/plain(纯文本)

2)text/html(html)

3)text/css(css)

4)application/javascript(js)

5)application/json

6)image/png

7)image/jpg

。。。。。。。

在浏览器和服务器交互过程中,有时为了提高效率,会将图片等一些固定不变的内容在浏览器本地的机器上的硬盘进行缓存,后续再进行请求时,就减小了网络开销。

2和3和body有关,数据包中如果没有body,也就不会有这两个字段。

4.User-Agent(简称UA)

例如

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0

是一行UA,其中

Mozilla/5.0 (Windows NT 10.0; Win64; x64):操作系统信息。

AppleWebKit/537.36:说明浏览器使用的是 AppleWebKit 渲染引擎,版本号是 537.36。

Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0:浏览器信息。

UA应用场景:

1)同时兼容老设备和新设备,根据系统和浏览器信息返回不同信息。

2)很多手机浏览器可以通过手动修改UA来转换为电脑页面。

5.Referer

例如:Referer: https://www.bilibili.com/video/BV1waXSYSEZ8/?spm_id_from=333.1007.tianma.1-1-1.click&vd_source=504824f6b9c030a5560def77dd4cedf1

描述了当前这个页面是从哪里来的。比如上述就是从哔哩哔哩页面来的。

Referer主要应用于搜索广告中统计点击数来算钱。

但是Referer可以被篡改,在14年左右,三大运营商经常会篡改Referer为通过自己的广告页面跳转的来获利,具体方法就是通过在自己提供的通信设备(路由器,交换机等)上部署程序来修改,这个时间产生了很大影响,被称为“运营商劫持”现象。

这一事件也促使了各大网站使用HTTPS来传输数据。因为HTTPS中的SSL加密可以将header(首行)和body都进行加密,网络上传输的都是密文了,而且如果运营商想要破解的话会被用户的浏览器感知。就避免了运营商劫持现象。

6.Cookie

报头属性中非常重要的部分。

Cookie本质上是一个浏览器这边本地持久化存储数据的机制。

浏览器作为电脑上的一个程序,可以通过调用系统提供的API来读写本地磁盘文件。理论上网页也可以,但是为了安全性,浏览器禁止了网页调用API来读写本地磁盘文件。

但是一些网站需要将一信息保存到浏览器这边,例如登录信息等,所以浏览器退而求其次,提供给了网站可以有限度地存储数据(按照键值对的方式,而且是程序员自定应的)的API,不允许网站随意访问文件系统。

例如:Cookie,LocalStorage,IndexDB等,其中LocalStorage和IndexDB较新一些,但是目前Cookie仍然是主流。

HTTP请求中的Cookie字段,就是把本地存储的Cookie信息发送到服务器这边,HTTP响应中会有一个Set-Cookie字段,就是服务器告诉浏览器你要在本地保存什么信息。

关于Cookie的一些重要结论:

1.Cookie从哪里来?

服务器返回给浏览器的,通常是首次访问/登录成功后。

2.Cookie到哪里去?

Cookie会存储到浏览器本地主机(访问浏览器的主机)的硬盘上,后续每次访问服务器都会带上Cookie。不同的客户端,保存的Cookie也是不同的,即使是同一个主机,使用不同的浏览器,Cookie也大概率会不同。

3.Cookie中存什么?

键值对格式的数据,这里的内容都是程序员自定义的,和query string一样外人无法理解。

4.Cookie在浏览器这边如何组织?

在本地硬盘中保存,是按照域名的不同为维度分别存储,例如,访问百度有一组Cookie,访问谷歌,则是另一组Cookie。

5.Cookie的用途是什么?

用来在客户端保存数据,其中最主要的是保存用户的身份标识,服务器可以通过身份标识来区分用户,其他的信息,如账号密码则不会保存在Cookie中,而是浏览器的另一个保存机制。

状态码

用于响应中的,标识响应的结果如何,当我们出现问题时,原因有很多种,就可以使用不同的数字来区分原因,就可以对症下药了。

上述状态码不需要全部记忆,只需要记住几个重要的即可。

1)200 OK:代表一切顺利。

2)404 Not Found:访问的资源没有找到。

3)403 Forbidden:请求的资源没有访问权限。

4)405 Method Not Allowed:服务器只支持GET请求,但是你发了个POST。

5)500 Internal Server Error:服务器内部错误(服务器挂了),自己写服务器时经常遇到。

6)504 Gateway Timeout:访问服务器超时,可能是服务器挂了,也可能是网挂了。

7)302 Move temporarily:重定向(临时重定向),因为有些域名会更换,但是许多老用户会使用老域名来访问,为了使老用户也可以访问,就会把访问老域名的请求重定向到新域名上。分为301 永久重定向,302 临时重定向。如果是永久重定向,浏览器就会把重定向的结果记录下来,后续再次访问,就直接访问重定向的目标地址即可。

在重定向的响应报文中,会有一个特殊的header叫做Location,就描述了要重定向的目标地址在哪里。

如何构造HTTP请求

1.通过代码构造

任何一个语言,只要可以进行网络编程,都可以构造HTTP请求,对于JAVA来说,需要使用ServerSocket/Socket(TCP中的socket  API)来编程。

public class HttpClient {
 private Socket socket;
 private String ip;
 private int port;
 public HttpClient(String ip, int port) throws IOException {
 this.ip = ip;
 this.port = port;
 socket = new Socket(ip, port);
    }
 public String get(String url) throws IOException {
 StringBuilder request = new StringBuilder();
 // 构造首行
request.append("GET " + url + " HTTP/1.1\n");
 // 构造 header
 request.append("Host: " + ip + ":" + port + "\n");
 // 构造 空行
request.append("\n");
 // 发送数据
OutputStream outputStream = socket.getOutputStream();
 outputStream.write(request.toString().getBytes());
 // 读取响应数据
InputStream inputStream = socket.getInputStream();
 byte[] buffer = new byte[1024 * 1024];
 int n = inputStream.read(buffer);
 return new String(buffer, 0, n, "utf-8");
    }
 public String post(String url, String body) throws IOException {
 StringBuilder request = new StringBuilder();
 // 构造首行
request.append("POST " + url + " HTTP/1.1\n");
 // 构造 header
 request.append("Host: " + ip + ":" + port + "\n");
比特就业课
request.append("Content-Length: " + body.getBytes().length + "\n");
 request.append("Content-Type: text/plain\n");
 // 构造 空行
request.append("\n");
 // 构造 body
 request.append(body);
 // 发送数据
OutputStream outputStream = socket.getOutputStream();
 outputStream.write(request.toString().getBytes());
 // 读取响应数据
InputStream inputStream = socket.getInputStream();
 byte[] buffer = new byte[1024 * 1024];
 int n = inputStream.read(buffer);
 return new String(buffer, 0, n, "utf-8");
    }
 public static void main(String[] args) throws IOException {
 HttpClient httpClient = new HttpClient("42.192.83.143", 8080);
 String getResp = httpClient.get("/AjaxMockServer/info");
 System.out.println(getResp);
 String postResp = httpClient.post("/AjaxMockServer/info", "this is 
body");
 System.out.println(postResp);
    }
 }

2.通过第三方软件构造

这里使用的是postman来构造HTTP请求。

通过设置HTTP数据报的各个内容即可send。

也可以通过form表单和ajax来构造,但是需要一定的前端基础。

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

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

相关文章

华为hcia——Datacom实验指南——配置手工模式以太网链路聚合

什么是以太网链路聚合&#xff08;Eth-trunk&#xff09; 是一种将多个物理链路捆绑在一起&#xff0c;让设备以为是一条大链路&#xff0c;能够增加带宽&#xff0c;增加冗余度&#xff0c;提升可靠性&#xff0c;实现负载平衡。 传输方式有两种 基于数据流传输和基于数据包…

【C语言6】数组和函数实践:扫雷游戏的简单实现

文章目录 一、扫雷游戏分析和设计1.1 扫雷游戏的功能说明1.2 游戏的分析和设计1.2.1 数据结构的分析1.2.2 文件结构设计 二、扫雷游戏的代码实现三、扫雷游戏的扩展总结 一、扫雷游戏分析和设计 1.1 扫雷游戏的功能说明 使用控制台实现经典的扫雷游戏游戏可以通过菜单实现继续…

LeetCode 热题 100----1.两数之和

LeetCode 热题 100----1.两数之和 题目描述 我的解法 语言&#xff1a;js 思路就是&#xff1a;用双重循环去找哪两个数字相加等于target&#xff0c;目前的时间复杂度为O(n2)&#xff0c;之后右优化思路再更新。

《模式和状态管理》知识总结三-EcuM与BswM模块的交互

前言 这篇文章主要搞清楚在模式管理中&#xff0c;BswM和EcuM各自的分工。距离学完模式管理也有几天时间了&#xff0c;写这篇文章算是复习一下。 EcuM及BswM交互总览 EcuM负责Ecu的上下电状态的处理&#xff0c;当Ecu处于正常运行状态的时候&#xff0c;EcuM会将Ecu的控制权…

客户需求模糊或频繁变更怎么办

应对客户需求模糊或频繁变更的关键在于 明确沟通、敏捷应对、科学决策。其中&#xff0c;明确沟通尤为重要&#xff0c;因为通过有效沟通&#xff0c;不仅能迅速厘清客户真实需求&#xff0c;还能及时发现隐藏问题&#xff0c;降低项目风险&#xff0c;为后续调整提供有力数据支…

动静态库-Linux 学习

在软件开发中&#xff0c;程序库是一组预先编写好的程序代码&#xff0c;它们存储了常用的函数、变量和数据结构等。这些库可以帮助开发者节省大量的时间和精力&#xff0c;避免重复编写相同的代码。当我们在 Linux 系统中开发程序时&#xff0c;经常会用到两种类型的程序库&am…

DeepSeek 系列模型:论文精读《A Survey of DeepSeek Models》

引言&#xff1a;一篇快速了解 DeepSeek 系列的论文。我在翻译时加入了一些可以提高 “可读性” 的连词 ✅ NLP 研 2 选手的学习笔记 笔者简介&#xff1a;Wang Linyong&#xff0c;NPU&#xff0c;2023级&#xff0c;计算机技术 研究方向&#xff1a;文本生成、大语言模型 论文…

机器人学习模拟框架 robosuite (3) 机器人控制代码示例

Robosuite框架是一个用于机器人模拟和控制的强大工具&#xff0c;支持多种类型的机器人。 官方文档&#xff1a;Overview — robosuite 1.5 documentation 开源地址&#xff1a;https://github.com/ARISE-Initiative/robosuite 目录 1、通过键盘或SpaceMouse远程控制机器人…

kakfa-3:ISR机制、HWLEO、生产者、消费者、核心参数负载均衡

1. kafka内核原理 1.1 ISR机制 光是依靠多副本机制能保证Kafka的高可用性&#xff0c;但是能保证数据不丢失吗&#xff1f;不行&#xff0c;因为如果leader宕机&#xff0c;但是leader的数据还没同步到follower上去&#xff0c;此时即使选举了follower作为新的leader&#xff…

【微知】如何查看Mellanox网卡上的光模块的信息?(ethtool -m enp1s0f0 看型号、厂商、生产日期等)

背景 服务器上插入的光模块经常被忽略&#xff0c;往往这里是定位问题最根本的地方。如何通过命令查看&#xff1f; 命令 ethtool提供了-m参数&#xff0c;m是module-info的意思&#xff0c;他是从光模块的eeprom中读取数据。&#xff08;应该是用i2c协议读取的&#xff09;…

yum源选要配置华为云的源,阿里云用不了的情况

curl -O /etc/yum.repos.d/CentOS-Base.repo https://repo.huaweicloud.com/repository/conf/CentOS-7-reg.repo

好数——前缀和思想(题目分享)

今天我的舍友去参加“传智杯”广东省的省赛&#xff0c;跟我说了这样一道题&#xff0c;他说他想不出来怎么去优化代码&#xff0c;怎么做都是套用两层for循环超时&#xff0c;下面我就根据题意&#xff0c;使用前缀和的算法去优化一下思路&#xff0c;题目本身是不难的&#x…

MWC 2025 | 移远通信大模型解决方案加速落地,引领服务机器人创新变革

随着人工智能、大模型等技术的蓬勃发展&#xff0c;生成式AI应用全面爆发。在此背景下&#xff0c;服务机器人作为大模型技术在端侧落地的关键场景&#xff0c;迎来了前所未有的发展机遇。 作为与用户直接交互的智能设备&#xff0c;服务机器人需要应对复杂场景下的感知、决策和…

springboot425-基于SpringBoot的BUG管理系统(源码+数据库+纯前后端分离+部署讲解等)

&#x1f495;&#x1f495;作者&#xff1a; 爱笑学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…

FineReport 操作注意

1.父单元格重复的时候&#xff0c;如何取消合并 效果如下&#xff1a; 只需要在单元格中&#xff0c;将数据设置为【列表】即可。 2.待定

3D手眼标定转换详细实施步骤及原理概述

3D手眼标定转换详细实施步骤及原理概述 一、手眼标定的核心目标二、3D手眼标定的原理概述一、基本概念与坐标系定义**二、数学建模与方程推导****1. 坐标变换的齐次矩阵表示****2. 手眼标定方程推导** **三、方程求解方法****1. 分离旋转与平移****2. 旋转矩阵求解****3. 平移向…

Verilog:SCCB控制器

目录 一、SCCB协议 &#xff08;1&#xff09;SCCB时序 &#xff08;2&#xff09;与I2C的区别 二、Verilog 实现 &#xff08;1&#xff09;设计要求 &#xff08;2&#xff09;设计要点 &#xff08;3&#xff09;模块完整代码 三、功能验证 &#xff08;1&#xff09;写…

与中国联通技术共建:通过obdiag分析OceanBase DDL中的报错场景

中国联通软件研究院&#xff08;简称联通软研院&#xff09;在全面评估与广泛调研后&#xff0c;在 2021年底决定采用OceanBase 作为基础&#xff0c;自研分布式数据库产品CUDB&#xff08;即China Unicom Database&#xff0c;中国联通数据库&#xff09;。目前&#xff0c;该…

大数据与网络安全讲座

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 大数据的价值为大家公认。业界通常以4个“V”来概括大数据的基本特征——Volume(数据体量巨大)、Variety(数据类型繁多)、Value(价值密度低)、Velocity(处理速度快…

张驰咨询:用六西格玛重构动力电池行业的BOM成本逻辑

在动力电池行业&#xff0c;BOM&#xff08;物料清单&#xff09;成本每降低1%&#xff0c;都可能改写企业的利润曲线。某头部企业的三元锂电池BOM成本曾较行业标杆高出11%&#xff0c;单电芯利润率被压缩至3%的生死线。然而&#xff0c;通过张驰咨询的六西格玛方法论&#xff…