ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

网络原理HTTP

网络原理HTTP 1. HTTP1.1 HTTP是什么HTTP超文本传输协议是常用的应用层协议基于TCP传输协议实现的平时我们打开一个网站就是通过HTTP协议传输数据的我们在浏览器输入网址URL例如baidu.com时浏览器给服务器发送一个HTTP请求然后服务器返回HTTP响应。1.2 理解HTTP协议工作过程前面说HTTP基于TCP的如果说TCP是管通信的那么HTTP是管说什么的。维度HTTPTCP所属层级应用层传输层关心什么数据的格式与语义说什么数据的可靠传输怎么送理解内容吗✅ 完全理解知道是网页请求❌ 完全不理解只是一串字节典型动作构造请求、解析响应三次握手、重传、排序、流控典型标识URL、方法、状态码IP 端口、序列号类比你写信的内容邮政系统我们访问一个网站时涉及不止一次HTTP响应检查网站的network模块就会显示每一次HTTP响应的结果2. HTTP协议格式2.1 抓包工具使用一个文本协议格式可以通过fiddler等抓包工具分析HTTP请求/响应的细节。进去fiddler点击一个HTTP右边弹出上下两个窗口上面请求下面响应点击raw查看数据格式点击右下角可以在记事本里查看。2.2 抓包工具原理客户端请求发给fiddlerfiddler再发给服务器服务器返回数据数据先到fiddler再到客户端。2.3 抓包结果1请求POST https://self.events.data.microsoft.com/OneCollector/1.0/ HTTP/1.1 Accept: */* APIKey: d019ee4b0f-a02c-84 Client-Id: NO_AUTH Content-Encoding: deflate Content-Type: application/bond-compact-binary Expect: 100-continue SDK-Version: EVT-Windows-C-No-3.4.276.7 Upload-Time: 1790732952702 Host: self.events.data.microsoft.com Content-Length: 606 Connection: Keep-Alive Cache-Control: no-cache首行方法url版本。header请求的属性冒号分隔的键值对每组之间用\n换行符分隔到空行结束。body空行后面的内容body可以为空如果body存在header里会有一个content-length来表示body的长度。注意如果Content-Encoding字段是gzip表示正文经过了 gzip 压缩——无论正文原本是文本还是二进制。压缩通过消除冗余减少字节数从而省带宽。2响应HTTP/1.1 403 Forbidden Content-Type: application/json Server: Microsoft-HTTPAPI/2.0 Strict-Transport-Security: max-age31536000 Collector-Error: All Events Throttled. Access-Control-Allow-Headers: Strict-Transport-Security,Collector-Error,Content-Type,Content-Length Access-Control-Allow-Methods: POST Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: * Access-Control-Expose-Headers: Collector-Error Date: Wed, 30 Sep 2026 01:49:16 GMT Content-Length: 52 {acc:0,rej:1,efi:{EventLevelThrottling:[0]}}首行版本号状态码状态码解释。header请求的属性冒号分隔的键值对每组之间用\n换行符分隔到空行结束。body空行后面的内容body可以为空如果body存在header里会有一个content-length来表示body的长度如果返回一个HTML页面那么HTML页面就是在body里。2.4 协议格式总结思考为什么HTTP报文里存在空行报文没有规定键值对的个数空行就是报头的结束标记也是与正文分隔符HTTP基于TCP进行传输的TCP是面向字节流传输的如果没有空行就会出现粘包问题。我们通过抓包可以判断bug在前端还是后端浏览器发出的请求错了→前端错误请求正确响应错误→后端错误请求正确响应正确显示错误→前端错误3. HTTP请求3.1 认识URL1URL基本格式https://www.example.com:443/path/to/page?key1value1key2value2#section └─┬─┘ └──────┬──────┘ └┬┘ └─────┬─────┘ └──────────┬─────────┘ └───┬───┘ scheme host port path query fragment 协议 主机名 端口 路径 查询参数 片段https协议名常见的有http和httpswww.example.com服务器地址此处是一个域名需要通过DNS解析成一个IP地址我们可以通过ping命令来获取IP地址如端口号有的URL端口号会被省略省略时浏览器会根据协议类型⾃动决定使用哪个端口例如http协议默认80端口https默认443端口。/path/to/page带层次的文件路径。?key1value1key2value2查询字符串本质是键值对键值对之间使用分隔前面的问号代表查询这些键值对的含义都是程序员自定义的。片段标识主要用于页面内跳转例如看java官方文档通过不同的片段标识跳转到不同章节。URL中可省略的部分协议名、IP地址、端口号、带层次的文件路径、查询字符串、片段标识。URL通俗解释http://万达茶百道:2/奶茶/杨枝甘露?甜度五分糖冰量去冰加料珍珠#杨枝甘露URL 部件店里对应http://点单方式柜台口头报明文or 小程序加密下单HTTPS万达茶百道IP 地址定位到这家店:2端口号2 号取餐窗口/奶茶/杨枝甘露path品类 → 杯名层层深入?甜度五分糖冰量去冰query string同一杯奶茶参数不同结果不同#杨枝甘露打开电子菜单时直接跳到那款的位置——只在你的手机里生效店员永远看不到2URL encode例如 / ? : 等这样的字符不能随意出现如 在前面说是URL里代表查询的含义这些字符需要进行转义。转义规则将需要转码的字符转为16进制然后从右到左取4位(不足4位直接处理)每2位做一位前⾯加上%编码成%XY格式 │ ① 转16进制 ▼ ASCII 0x2B十进制 43 │ ② 判断0x2B 0x80单字节不到4位直接处理的情况 ▼ 十六进制就是 2B —— 正好 2 位 1 字节无需切分 │ ③ 前面加 % ▼ %2B 两个加号 → %2B%2B3.2 认识方法方法说明支持的HTTP协议版本GET获取资源1.0、1.1POST传输实体主体1.0、1.1PUT传输文件1.0、1.1HEAD获得报文首部1.0、1.1DELETE删除文件1.0、1.1OPTIONS询问支持的方法1.1TRACE追踪路径1.1CONNECT要求用隧道协议连接代理1.1LINK建立和资源之间的联系1.0UNLINE断开连接关系1.01get方法最常用的http方法用于获取服务器上某个资源在浏览器里直接输入URLwww.baidu.com此时浏览器就会发出get请求。通过fiddler抓包工具可以看到get请求特点首部第一行为GETURL的查询条件可以为空也可以不为空header部分有若干个键值对结构body部分为空2post方法多用于用户输入数据提交给服务器例如用户登录。通过HTML中的form标签可以构造POST请求,或者使用JavaScript的ajax也可以构造POST请求。登录boss直聘输入账号信息之后抓包post请求特点首行第一部分为POSTURL的查询条件一般为空(也可以不为空)header部分有若干个键值对body部分一般不为空body里的数据格式一般通过content-type指定的body长度有content-length指定的。3GET和POST的区别get一般用于获取数据post一般用于提交数据。get的body通常为空需要传输的数据通过query传输post的query通常为空需要传输的数据装到body里传输。get的请求一般是幂等的post不是幂等的多次请求得到的结果一样就是幂等例如查询10次结果都一样提交10次订单就产生10个订单。get可以被缓存post不能被缓存承接幂等性GET 靠地址找货缓存可放心复用POST 每次执行都改变世界缓存复用就是造假。4其他方法PUT修改与POST新增相似只是具有幂等特性⼀般用于更新。DELETE删除服务器指定资源。OPTIONS返回服务器所支持的请求方法。HEAD类似于GET只不过响应体不返回只返回响应头。TRACE回显服务器端收到的请求测试的时候会用到这个。CONNECT预留暂无使用。3.3 认识请求报头headerheader的整体格式是键值对结构1Host表示服务器的地址和端口。地址必须写端口可省略——省略时按协议补默认值http → 80https → 443。例如访问 https://www.gitee.com完整形式是www.gitee.com:443因 443 是默认端口实际就写成www.gitee.comHost 把 URL 的主机部分抄进 HTTP 报文让一台服务器一个 IP 挂多个站能分辨你要哪个站虚拟主机。HTTP/1.1 起强制要求携带缺失返回 400。注意www只是一个子域名不是必须的。gitee.com和www.gitee.com都能访问有些网站必须加www才能访问是因为它只配了www的DNS记录没配裸域名的反过来也有网站必须不加 www才能访问。2Content-Length表示body中的数据长度前提是存在body服务器如何区分一个完整的请求如果没有body就读到空行就行如果有body则必然存在content-length找到空行空行之后就是body从空行后开始按照content-length长度读取字节数即可3Content-Type表示请求的body中的数据格式前提是存在body大类代表类型对应文件一句话用途text/*text/html.html网页文档浏览器渲染成页面application/*application/json.json前后端 API 传 JSON本类还有表单/上传/二进制见下image/*image/jpeg.jpg / .jpeg图片注意标准写法是 jpeg没有 image/jpgaudio/*audio/mpeg.mp3音频video/*video/mp4.mp4视频multipart/*multipart/form-data—文件上传一个 body 分多段font/*font/woff2.woff2网页字体如果一个请求/响应虽然有 body 但是没有 Content-Type 或者 Content-Length就是一个非法的请求/响应。比如响应中如果没有 Content-Type浏览器会根据 body 中的数据猜一个格式有较大的概率能猜对。如果没有 Content-Length浏览器也能猜按照下一个请求一定是 GET/POST 开头。4User-Agent(简称UA)Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36Windows NT 10.0; Win64; x64表示操作系统信息AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36表示浏览器信息5Referer表示当前这个页面从哪个页面跳转过来的。浏览器的回退和referer不同回退不依赖http协议浏览器自身维护一个“栈”保存访问记录。6Cookiecookie里存储了一个字符串键值对的形式表现这个数据可能是通过客户端网页自行通过JS写入的也可能来自于服务器服务器在响应的header里通过Set-Cookie字段给浏览器返回数据。登录操作最初没有Cookie发出登录请求服务器响应返回Set-Cookie用户访问网站其他页面就会带着获取的Cookie信息来访问。登录成功 → 服务器返回 sessionIdSet-Cookie里键值对之一 → 浏览器存 Cookie → 后续请求自动带 Cookie → 服务器认出你不用重新登录理解登录过程左客户端右服务器注意Cookie存浏览器就是存本地7session和Cookie的联系Cookie是票据Session是档案柜数据存在服务器的档案柜里Cookie 里只放一张写着柜号sessionId的票。① 你登录成功 ② 服务器生成一份 Session存你的用户信息放在自己档案柜里 ③ 服务器把这份 Session 的编号sessionId放进响应头 Set-Cookie: sessionIdabc123; HttpOnly ④ 浏览器把这条 Cookie 存在本地 ⑤ 之后每次请求浏览器自动带上Cookie: sessionIdabc123 ⑥ 服务器凭编号回档案柜查你的信息 → 确认是你返回你的数据桌面应用app不依赖Cookie因为数据可以存本地文件系统。3.4 认识请求正文body数据格式Content-Type数据格式示例内容说明application/jsonJSON{key: value}前后端交互最常用的数据格式text/htmlHTMLdivhello/div网页源码浏览器渲染成页面text/cssCSS* { font-size: 12px; }样式表控制网页外观application/javascriptJSlet n 10;脚本代码控制网页行为image/png二进制二进制内容图片浏览器解析成图像显示登录网站请求POST /wapi/zpCommon/toggle/all HTTP/1.1 Host: www.zhipin.com Connection: keep-alive Content-Length: 39 Content-Type: application/x-www-form-urlencoded Accept: application/json, text/javascript, */*; q0.01 Accept-Encoding: gzip, deflate, br, zstd Accept-Language: zh-CN,zh;q0.9,en;q0.8 Origin: https://www.zhipin.com Referer: https://www.zhipin.com/city/ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ... Edg/154.0.0.0 X-Requested-With: XMLHttpRequest Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty sec-ch-ua-platform: Windows sec-ch-ua-mobile: ?0 system9E2145704D3D49648DD85D6DDAC1CF0D4. HTTP响应4.1 认识状态码1200 OK场景的状态码表示响应成功然后响应的body经过压缩后的数据2404 Not Found输入www.sogou.com/index2.htmlfiddler浏览器3403 Forbidden用户访问被拒绝例如不登录访问Gitee的私有仓库。4405 Method Not AllowedHTTP中所支持的方法有 GET、POST、PUT、DELETE 等。但是对方的服务器不一定都支持所有的方法或者不允许用户使用一些其他的方法。5500 Internal Server Error服务器内部错误服务器代码执行过程遇到特殊情况如服务器异常崩溃。6504 Gateway Timeout服务器负载较大的时候处理单条数据消耗的时间很长可能出现超时的情况。7302 Move temporarily临时重定向。就相当于手机号码中的呼叫转移功能。比如我本来的手机号是 186-1234-5678后来换了个新号码 135-1234-5678那么不需要让我的朋友知道新号码只要我去办理一个呼叫转移业务其他人拨打 186-1234-5678就会自动转移到 135-1234-5678 上。8301 Moved Permanently永久重定向。当浏览器收到这种响应时后续的请求都会被自动改成新的地址。9状态码小结类别类别说明原因短语1XXInformational信息性状态码接收的请求正在处理2XXSuccess成功状态码请求正常处理完毕3XXRedirection重定向状态码需要进行附加操作以完成请求4XXClient Error客户端错误状态码服务器无法处理请求5XXServer Error服务器错误状态码服务器处理请求出错4.2 认识响应报头Content-Type Content-Length等属性和请求报头一个含义。1content-type常见取值text/htmlbody 数据格式是 HTMLtext/cssbody 数据格式是 CSSapplication/javascriptbody 数据格式是 JavaScriptapplication/jsonbody 数据格式是 JSON4.3 认识响应正文body1text/html2text/css3application/javascript4application/json5. 构造HTTP请求通过Java socket构造HTTP请求package network.HTTP; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class HttpClient { private Socket socketnull; public HttpClient(String serverIp,int port) throws IOException { socketnew Socket(serverIp,port); } public void get(String path) throws Exception{ //构造Http结构字符串 try(InputStream inputStreamsocket.getInputStream(); OutputStream outputStreamsocket.getOutputStream()){ String firstLine GET path HTTP/1.1\r\n; String headerHost: socket.getInetAddress().getHostAddress():socket.getPort()\r\n; String blankLine\n; String httpRequestfirstLineheaderblankLine; outputStream.write(httpRequest.getBytes()); outputStream.flush(); byte[] bytesnew byte[1024*1024]; int ninputStream.read(bytes); String httpResponsenew String(bytes,0,n); System.out.println(httpResponse); }catch (Exception e){ e.printStackTrace(); } return; } public static void main(String[] args) throws Exception{ HttpClient httpClientnew HttpClient(www.baidu.com,80); httpClient.get(/);//获取首页 } }响应结果返回HTML
返回列表