目录
1 HTTP是什么
2 HTTP协议格式
3 HTTP请求(Request)
3.1 认识URL
3.2 方法
3.3 认识请求"报头"(header)
3.3.1 Host
3.3.2 Content-Length
3.3.3 Content-Type
3.3.4 User-Agent (简称UA)
3.3.5 Referer
3.3.6 Cookie和Session
4 HTTP响应详解
4.1 认识"状态码"(statuscode)
4.2 认识响应"报头"(header)
4.3 认识响应"正⽂"(body)
5 通过form表单构造HTTP请求
6 通过ajax构造HTTP请求
7 通过Javasocket构造HTTP请求
1 HTTP是什么
HTTP(全称为"超⽂本传输协议")是⼀种应⽤⾮常⼴泛的应⽤层协议.
什么叫超文本呢? 就是超越文本, 不止可以传输字符串, 还能够传输图片, 文字, 视频, 音频....
尤其对Java开发来说, http比tcp还重要.
http诞⽣与1991年.⽬前已经发展为最主流使⽤的⼀种应⽤层协议
https://i-blog.csdnimg.cn/direct/7182be31b1e1431d9265f8ef14f1822b.png" width="875" />
但实际上, 我们的网络大多还是以1.1为主, 更何况是3.0了, 这应该是还存放在实验室的版本.
https://i-blog.csdnimg.cn/direct/b2344dc0bea64c16bdc362c6b6b119ca.png" width="1627" />
https://i-blog.csdnimg.cn/direct/c60446ea8bcd4a7495e7e7f34f3fc2f5.png" width="1142" />
https://i-blog.csdnimg.cn/direct/28f80098e86840e2a395483a639a5f43.png" width="1429" />
2 HTTP协议格式
HTTP是⼀个⽂本格式的协议.可以通过Chrome开发者⼯具或者Fiddler抓包,分析HTTP请求/响应 的细节. 抓包工具本质就是一个代理.
https://i-blog.csdnimg.cn/direct/a0870be1e772431fa45cd2f13baaa24b.png" width="1406" />
https://i-blog.csdnimg.cn/direct/1bc3f91d58324e81a3d05d7f1f314d38.png" width="1665" />
https://i-blog.csdnimg.cn/direct/fc7357f103cc4a3b9eef7a7a2b229aa1.png" width="1146" />
https://i-blog.csdnimg.cn/direct/a03a71ea75134ec7ae50025ca50ff1d2.png" width="1330" />
抓包⼯具的使⽤
以Fiddler为例 (下载地址:https://www.telerik.com/fiddler/)
安装过程⽐较简单,⼀路next即可.
https://i-blog.csdnimg.cn/direct/2f31c8b5e1cb41d5bf6e8b61743d9279.png" width="1402" />
https://i-blog.csdnimg.cn/direct/16b5a22483be4bc5840e454911dffee1.png" width="2418" />
https://i-blog.csdnimg.cn/direct/97f7018c85cc4ae28510f1d1f31f7cf0.png" width="1266" />
打开一个网页, 就会涉及到多次浏览器和服务器之间的交互, 接下来我会以sougou浏览器的抓包结果为例, 介绍http协议的格式.
这是打开sougou浏览器的请求
https://i-blog.csdnimg.cn/direct/df82242da6dd42cb9d8acab7f1394eae.png" width="1521" />
这是sougou浏览器的响应
https://i-blog.csdnimg.cn/direct/8b7ed87f334742b8b7e5ff200bea2b02.png" width="2685" />协议格式总结
https://i-blog.csdnimg.cn/direct/c43609d32b6842a1bde2c1229ed3d666.png" width="1168" />
接下来, 我们一个部分挨个看.
3 HTTP请求(Request)
3.1 认识URL
这是首行
https://i-blog.csdnimg.cn/direct/d9cbfe1b04494bd49c1818920403b685.png" width="1396" />
https://i-blog.csdnimg.cn/direct/543e70f99cb34103833d999b28ca784d.png" width="907" />
平时我们俗称的"⽹址"其实就是说的URL. 互联⽹上的每个⽂件都有⼀个唯⼀的URL,它包含的信息指出⽂件的位置以及浏览器应该怎么处理它. URL的详细规则由因特⽹标准RFC1738进⾏了约定. 同时这个RFC也是约定了UDP,TCP,IP等网络协议的细节.
https://i-blog.csdnimg.cn/direct/f551503a23b440a782ead40c6a770392.png" width="1941" />
https://i-blog.csdnimg.cn/direct/e961ca1d57e441f0a08e6ca49207295f.png" width="1306" />
https://i-blog.csdnimg.cn/direct/2d2bd850ad8b48a6b82abc3565a10aca.png" width="1445" />
https://i-blog.csdnimg.cn/direct/032afe1a480440868e6705f36cd8c7d4.png" width="1920" />
以后你也去开发一个xxx网站, 此时的这个内容也是需要你自定义的, 这就要根据实际需求考虑了.
实际上,对于URL来说,上述的几个部分,有的是可以省略的, 不是哪个部分必须得有.
https://i-blog.csdnimg.cn/direct/1cafdc0d487c425ca75264a24e1cc048.png" width="2063" />
https://i-blog.csdnimg.cn/direct/a2bda214b7e5487990af0af7408054da.png" width="1910" />
https://i-blog.csdnimg.cn/direct/6e91b90fba024932a9dfe60d25aa5f31.png" width="1675" />
https://i-blog.csdnimg.cn/direct/31f61b3772364cca97fe545c2905d80b.png" width="962" />
正是上述的灵活性 , 使http可以根据不同的需求场景, 进行一些"自定制"工作. 也就使 http协议成了非常广泛使用的协议.
关于URLencode
像 / ? : 等这样的字符,已经被url当做特殊意义理解了.因此这些字符不能随意出现.
⽐如,某个参数中需要带有这些特殊字符,就必须先对特殊字符进⾏转义.
⼀个中⽂字符由UTF-8或者GBK这样的编码⽅式构成,虽然在URL中没有特殊含义,但是仍然需要进 ⾏转义.否则浏览器可能把UTF-8/GBK编码中的某个字节当做URL中的特殊符号.
https://i-blog.csdnimg.cn/direct/1ce08d841db64c8ead70aeadd2b8c5a8.png" width="1257" />
https://i-blog.csdnimg.cn/direct/8c75a519fd9047808ad3c343718faeec.png" width="1051" />
https://i-blog.csdnimg.cn/direct/73bec0f31644404185359a5d0c5d25ac.png" width="2123" />
3.2 方法
https://i-blog.csdnimg.cn/direct/0059dc687589470e9e2e273b583b6180.png" width="1414" />
https://i-blog.csdnimg.cn/direct/f311302628ce4fcb9dca5693a952bd73.png" width="2813" />
https://i-blog.csdnimg.cn/direct/71689db7ceba41d7ba791a9a8bf1ac21.png" width="2173" />
https://i-blog.csdnimg.cn/direct/8af4f2b725f3450b92b7ff7c38d6457b.png" width="1164" />
GET请求一般没有body
POST请求最常见的场景
登录(以登录gitee为例)
https://i-blog.csdnimg.cn/direct/0e0b26b4a7d44aefae265d97669a5429.png" width="1725" />
https://i-blog.csdnimg.cn/direct/fa4c5e5a0134430c8b7c5d53010a9b1f.png" width="2142" />
https://i-blog.csdnimg.cn/direct/ea311613d192462ea2d730839fc269ad.png" width="2488" />
有人会问, 那通过抓包是不是就可以分析出密码. 这是不可能的.
https://i-blog.csdnimg.cn/direct/ea30d4e42e994b42857b37f9463ceada.png" width="1536" />
因为信息量有损失了, 比如, 给你猪肉,很容易把猪肉做成火腿肠.
并且两块一样的猪肉,做出的火腿肠也差不多.(服务器只要对比密文就知道密码是否正确了)
给你火腿肠,你能推导出猪肉是啥样的嘛?
上传
https://i-blog.csdnimg.cn/direct/d19781de94bb49bcafccf7bd92d6a503.png" width="2289" />
https://i-blog.csdnimg.cn/direct/e513699e99c0475f99386d570a2fd4c2.png" width="1745" />
https://i-blog.csdnimg.cn/direct/4c2511725e7f4171adab626de161ab76.png" width="1851" />
https://i-blog.csdnimg.cn/direct/4e48a871cd9048879a608cb1e6234930.png" width="1446" />
https://i-blog.csdnimg.cn/direct/ccf7765b57d44e3eadf2eb946ba62f2a.png" width="1353" />
https://i-blog.csdnimg.cn/direct/74ff1046481f412b84d8f93e7a0b881e.png" width="1401" />
https://i-blog.csdnimg.cn/direct/2ad1a68a977442c197b2329b97171437.png" width="1814" />
https://i-blog.csdnimg.cn/direct/1b04a15d0bf74fa083bc3d77d917d656.png" width="1093" />
https://i-blog.csdnimg.cn/direct/dc8e1f9cceb74c7589b2b5a522e82068.png" width="1653" />
https://i-blog.csdnimg.cn/direct/1050299b115e4c20bd409e969a97fd09.png" width="1897" />
其他⽅法
• PUT与POST相似,只是具有幂等特性,⼀般⽤于更新
• DELETE删除服务器指定资源
• OPTIONS返回服务器所⽀持的请求⽅法
• HEAD类似于GET,只不过响应体不返回,只返回响应头
• TRACE回显服务器端收到的请求,测试的时候会⽤到这个
• CONNECT预留,暂⽆使⽤
这些方法比较少见, 认识一下即可.
3.3 认识请求"报头"(header)
header 的整体的格式也是"键值对"结构.
每个键值对占⼀⾏.键和值之间使⽤ :空格 分割.
报头的种类有很多,此处仅介绍⼏个常⻅的.
.https://i-blog.csdnimg.cn/direct/cc9dde65781746878b5940f53cc372ae.png" width="1843" />
https://i-blog.csdnimg.cn/direct/462ee71e893a4ce580d76471bc8fe563.png" width="1750" />
3.3.1 Host
表⽰服务器主机的地址和端⼝.
https://i-blog.csdnimg.cn/direct/d78d1b7487e64d329660ce2d86d31c4a.png" width="1485" />
3.3.2 Content-Length
表⽰body中的数据⻓度
https://i-blog.csdnimg.cn/direct/01651472aa8c48c18fbeac28c154851c.png" width="1121" />
https://i-blog.csdnimg.cn/direct/5f5e1b560dc8498aa012ecf85f609bdd.png" width="951" />
3.3.3 Content-Type
表⽰请求的body中的数据格式.
https://i-blog.csdnimg.cn/direct/449248d460f34c65a10af0be8170f69e.png" width="785" />
在HTTP请求中,Content-Type有三种主要的情况.
https://i-blog.csdnimg.cn/direct/8d7fe114c7e441508e2ede7af12402f0.png" width="1551" />
https://i-blog.csdnimg.cn/direct/deb0b36879f1488f907df8997de51009.png" width="1835" />
https://i-blog.csdnimg.cn/direct/b5b7503b1fa64bdfbb011159263dc95c.png" width="1880" />
https://i-blog.csdnimg.cn/direct/1c6cf08c06ff4ca0b316c94f17877e84.png" width="1583" />
https://i-blog.csdnimg.cn/direct/4a3856fe855045a28d9b06005c2d0928.png" width="1236" />
https://i-blog.csdnimg.cn/direct/9bd2b11f87ee41ffb51a29a64b5b6c74.png" width="1709" />
3.3.4 User-Agent (简称UA)
https://i-blog.csdnimg.cn/direct/6e9af7230bb741eab94b2fab58dbd397.png" width="2569" />
互联网发展的早期, 网站,主要就是文字) (早期的网站,相当于就是把报纸,杂志这样的传统媒体,搬到电脑上), 随着浏览器不断更新,支持的功能越来越丰富了.
图片
js(交互)
播放视频/音频
浏览器可以支持更多的功能了.
新的浏览器支持的功能更多, 旧的浏览器支持的功能更少.
同一时刻, 市面上有的人使用的是新浏览器, 有的是使用旧浏览器.
如果你开发一个网站, 你该怎么处理这种差异呢? 不论站在哪边, 都会影响用户的体验.
因此聪明的程序员们就想了个办法. 浏览器在发起http请求的时候, 向服务器自报家门. 告诉服务器,
我是使用啥系统, 啥浏览器上网的. 服务器就可以根据这个信息,来分别对待. 这样就不会影响用户的体验.
到今天为止,各大浏览器的功能都差不多了. UA的意义就小了不少. UA现在主要用来区分,PC端还是移动端.
3.3.5 Referer
表⽰这个⻚⾯是从哪个⻚⾯跳转过来的.
如果你是通过浏览器地址来直接输入url / 点击收藏夹打开的网页,这个请求中是不带 referer.
但是如果你是点击了某个网页的内容,产生了跳转,就是带referer.
https://i-blog.csdnimg.cn/direct/74601fe140524792b05409d2a03112fd.png" width="856" />
https://i-blog.csdnimg.cn/direct/8f98429449b740678bfdc2ae6271139b.png" width="2616" />
https://i-blog.csdnimg.cn/direct/ee3dde1a687e4ff084c774b101f21be1.png" width="2448" />
https://i-blog.csdnimg.cn/direct/2a09a32c3ce24896a51f933f734d253e.png" width="1578" />
https://i-blog.csdnimg.cn/direct/fda774e14c374936b8c809ff0c9bd06d.png" width="2255" />
这个行为是违法行为, 被称为"运行商劫持", 当时百度搜狗这种公司没少和运行商打官司, 但是打官司是一个很长的流程, 官司100%能打赢!但是打赢之后,3年过去了!!!
3年里, 由于这种运营商劫持造成的损失已经难以估量了.
所以HTTPS乘势而出, 通过加密传输来反制这种现象, 所以我们现在的大部分网站都是HTTPS协议的.
3.3.6 Cookie和Session
是浏览器本地存储的一种机制.
https://i-blog.csdnimg.cn/direct/d702ad124232467b8eeb3a93f14f98de.png" width="1791" />
https://i-blog.csdnimg.cn/direct/e7ecea724ae844f48b9f0d1f40ea8da0.png" width="1560" />
https://i-blog.csdnimg.cn/direct/152aa57154f747c6b5af17c4a258042d.png" width="1520" />
那有人可能会问了, 浏览器保存数据为啥要放到cookie中, 直接写入硬盘放入一个文件里, 不行吗? 显然是不行的, 如果让网页轻易的访问你的文件系统, 是非常危险的, 如果你上某些小网站, 网站给你写了个病毒程序或者将你硬盘的数据全部情况, 那你不就寄了.
为了保证安全, 浏览器会对网页的功能做出限制. (禁止直接访问硬盘,就是其中一个规则).
为了保证安全,同时又能存储数据, 浏览器就提供了Cookie 功能(后来又有了其他功能).
cookie里的数据是按照键值对的方式来存储一些字符串, 这些键值对往往都是服务器返回来的, 浏览器把这些键值对按照域名维度, 分类存储. 不同的网站的cookie是独立的, 这些cookie的内容都是程序员自定义的.
一个网站中的cookie会存储很多键值对, 这其中相当重要的一个键值对, 是用来表示用户的"身份信息". 这个身份信息标识当前请求是来自于哪个用户的.
假设你去一家医院看病,医院有一套电子医疗系统,用于管理病人的信息和就诊记录。
1. 你第一次去医院
注册就诊卡
-
就诊卡:你第一次去医院时,需要注册一个就诊卡。你填写了个人信息(如姓名、身份证号、联系方式等),医院给你发了一张就诊卡。
-
就诊卡的作用:这张就诊卡就像是浏览器中的 Cookie,它保存了你的身份信息。
医院系统中的记录
-
电子病历:医院的系统会根据你的就诊卡信息,创建一个电子病历,记录你的详细信息(如病史、过敏史、检查结果等)。
-
电子病历的作用:这个电子病历就像是服务器中的 Session,它保存了你的详细信息和就诊记录。
2. 你再次去医院
出示就诊卡
-
出示就诊卡:你再次去医院时,需要出示就诊卡。医院的工作人员通过就诊卡上的编号,查找你的电子病历。
-
电子病历的作用:医院的系统会根据就诊卡上的编号,找到你的电子病历,获取你的详细信息和就诊记录。
3. 就诊过程
挂号
-
挂号:你通过就诊卡挂号,医院的系统会在你的电子病历中记录挂号信息。
-
就诊:你去看医生时,医生通过就诊卡上的编号,调出你的电子病历,查看你的病史和检查结果,然后进行诊断和治疗。
-
检查:你去做检查(如验血、拍X光等),检查结果会被记录在你的电子病历中。
-
取药:你去药房取药时,药房工作人员通过就诊卡上的编号,调出你的电子病历,查看医生的处方,然后给你发药。
4. 保存记录
保存就诊记录
-
更新电子病历:每次就诊结束后,医院的系统会更新你的电子病历,记录这次就诊的详细信息(如诊断结果、治疗方案、检查结果等)。
-
保存就诊卡:你保存好就诊卡,下次再来医院时,可以继续使用这张就诊卡,医院的系统会根据就诊卡上的编号,找到你的电子病历,继续记录你的就诊信息。
技术对应关系
-
就诊卡:浏览器中的 Cookie,保存了用户的身份信息(如用户ID)。
-
电子病历:服务器中的 Session,保存了用户的详细信息和状态(如病史、检查结果等)。
-
医院系统:服务器,管理所有的用户信息和就诊记录。
-
用户登录:
-
你第一次登录医院系统时,系统会生成一个唯一的用户ID,并保存在你的就诊卡上(Cookie)。
-
医院系统还会在服务器上创建一个Session,保存你的详细信息(如病史、检查结果等)。
-
-
后续访问:
-
你再次访问医院时,出示就诊卡(Cookie),医院系统通过就诊卡上的用户ID,找到对应的Session,获取你的详细信息。
-
医院工作人员根据Session中的信息,处理你的挂号、就诊、检查和取药等请求。
-
-
https://i-blog.csdnimg.cn/direct/cc3227540b594cb2ad5c05b29f9ba0d2.png" width="1717" />
https://i-blog.csdnimg.cn/direct/92159e644c3f4c028b26f01e9f2e1a08.png" width="1707" />
4 HTTP响应详解
https://i-blog.csdnimg.cn/direct/70066526b01a4b4f9b11a406422e95a3.png" width="1205" />
4.1 认识"状态码"(statuscode)
状态码表⽰访问⼀个⻚⾯的结果.(是访问成功,还是失败,还是其他的⼀些情况...).
以下是一些比较常见的状态码
https://i-blog.csdnimg.cn/direct/b8c5497b8e7940b1913dee45d7224d41.png" width="1183" />
https://i-blog.csdnimg.cn/direct/c7b5b1d4d5b942e18f0745e3955d9d6f.png" width="1349" />
4.2 认识响应"报头"(header)
响应报头的基本格式和请求报头的格式基本⼀致.
类似于 Content-Type , Content-Length 等属性的含义也和请求中的含义⼀致.
Content-Type
响应中的Content-Type常⻅取值有以下⼏种:
text/html :body数据格式是HTML
• te xt/css :body数据格式是CSS
• a pplication/javascript :body数据格式是JavaScript
• a pplication/json :body数据格式是JSON
4.3 认识响应"正⽂"(body)
正⽂的具体格式取决于Content-Type.观察上⾯⼏个抓包结果中的响应部分.
1) text/html
https://i-blog.csdnimg.cn/direct/02c7ddbe686f44cdaff7b0383d458081.png" width="1380" />
2) text/css
https://i-blog.csdnimg.cn/direct/66f8e9b0de194273a3c36c4bd258ba12.png" width="1360" />
3) application/javascript
https://i-blog.csdnimg.cn/direct/8b7044182ec5410099d349d5b4296b1d.png" width="1367" />
4) application/json
https://i-blog.csdnimg.cn/direct/87acbe4793384d2698f796427b0222b1.png" width="1349" />
5 通过form表单构造HTTP请求
实际开发中, 经常需要手动的构造出http协议的请求来.
这些方式有
1.通过html中的form表单
⒉通过js的ajax
3.Java代码(其他各种语言的代码)
4.借助一些第三方工具
HTML也是一种编程语言.和Java,C风格差异很大. Java和C都是在表述一个"逻辑", 先干啥,后干啥,什么情况要干啥, 是一种动作. 而HTML则是在描述一个"形态", 一个网页上,都有啥.
https://i-blog.csdnimg.cn/direct/3f6af72eef43410a8483d3dc2cf9845d.png" width="1008" />
这里推荐使用VSCode, 怎么用这里就不做过多赘述了.
https://i-blog.csdnimg.cn/direct/cb21670dfbd44d8d8b633aca71bef19a.png" width="2413" />
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><form action="https:www.sogou.com" method="get"><input type="text" name="aaa"><input type="text" name="bbb"><input type="text" name="ccc"><input type="submit" value="提交"></form>
</body>
</html>
https://i-blog.csdnimg.cn/direct/5c8430e2f09045a39a76cad6f1e0cd8a.png" width="1859" />
https://i-blog.csdnimg.cn/direct/40df46b3e2434794981d5956de1cd20d.png" width="1229" />
https://i-blog.csdnimg.cn/direct/35b9cabe92b64fcdae431e566ae921fa.png" width="2390" />
form表单,只能支持get和post,不能支持put/delete/options 等其他方法.....
6 通过ajax构造HTTP请求
现在更经常会使用ajax的方式来构造http请求. ajax 全称Asynchronous Javascript And XML,是2005年提出的⼀种JavaScript给服务器发送HTTP请求的⽅式.
https://i-blog.csdnimg.cn/direct/793eadcad9764d8fb3771a7d27e6a5b6.png" width="1516" />
https://i-blog.csdnimg.cn/direct/4c57571adefa4f669d331bbcf5a899c1.png" width="958" />
https://i-blog.csdnimg.cn/direct/873ba034e90d417488e7f56874ece2f3.png" width="1512" />
https://i-blog.csdnimg.cn/direct/be33acb609684ac69953d63af0853a9a.png" width="1321" />
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src="https://code.jquery.com/jquery-3.7.1.min.js"></script><script>// 正式的 js 代码, 就要调用上面 jQuery 中的方法了. $.ajax({type: 'post',url: 'https/www.sogou.com',contentType: 'application/x-www-form-urlencoded',data: 'aaa=111&bbb=222',success: function(body) {console.log('ok')}});</script>
</body>
</html>
https://i-blog.csdnimg.cn/direct/80da0492155346968f695d97b6d04507.png" width="2118" />
https://i-blog.csdnimg.cn/direct/406562cb1b7f40ea9f07958016af4a44.png" width="1408" />
https://i-blog.csdnimg.cn/direct/8e4ee50dd8fb42e091ed4ad0852212b6.png" width="2550" />
https://i-blog.csdnimg.cn/direct/5ecc8da8e14b41b39a3cd5d8c7186ec3.png" width="904" />
7 通过Javasocket构造HTTP请求
https://i-blog.csdnimg.cn/direct/c14e7ee0a3084375a5a80b82f9530f29.png" width="1954" />
事实上, 除了上述写代码的工具外, 还可以通过第三方工具构造http请求, 这其中介绍一款软件postman, 它还有个对象叫postwoman, 也是一个http客户端. postman还可以根据你这边构造的请求,自动生成代码.
https://i-blog.csdnimg.cn/direct/a0e5658b04bc4d1a904b3a47f4fa3e35.png" width="2520" />