前言:
大家好,我是良辰丫,上一篇文章我们已经了解过了http协议,这篇文章我将带领大家去学习http协议的一些属性,http协议格式,请求格式,常见请求方法,请求报文,请求正文.跟随我的脚步,一起遨游http的海洋.
个人主页:良辰针不戳
所属专栏:javaEE初阶
励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。
期待大家三连,关注,点赞,收藏。
作者能力有限,可能也会出错,欢迎大家指正。
愿与君为伴,共探Java汪洋大海。
在上一篇文章中,我们简单的认识了协议的格式以及如何使用fiddler进行抓包.我们先来看一个图,简单的回忆一下http的协议格式.
- 首行,也就是请求行.
- 请求包头header
- 空行,表示请求报文的结束标记.
- 请求正文:就是body内容.
在 HTTP 报文中为什么要存在 “空行”?
- HTTP 协议并没有规定报头部分的键值对有多少个. 空行就相当于是 “报头的结束标记”, 或者
是 “报头和正文之间的分隔符”.- HTTP 在传输层依赖 TCP 协议, TCP 是面向字节流的. 如果没有这个空行, 就会出现 “粘包问题”.
URL这个关键字想必大家已经见过很多次了,但是这到底是是一个什么东西哦,还是有点不太明白,没关系,我来带大家一起了解.
URL
(Uniform Resource Locator 统一资源定位符),我们平时所说的访问某个网址就是访问URL地址
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它. URL 的详细规则由 因特网标准RFC1738 进行了约定.
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎处理它。
协议方案名,登录信息认真,服务器地址,服务器端口号,带层次的文件路径,查询字符串,片段标识符.
- URL访问地址的时候,有些信息会被省略.
- https : 协议方案名. 常见的有 http 和 https, 也有其他的类型. (例如访问 mysql 时用的jdbc:mysql )
- user:pass : 登陆信息. 现在的网站进行身份认证一般不再通过 URL 进行了. 一般都会省略
- 服务器地址.,可以是一个 “域名”, 域名会通过 DNS 系统解析成一个具体的 IP 地址. (通过 ping 命令可以看到真实的ip地址)
- 端口号: URL 中端口号被被省略了. 当端口号省略的时候, 浏览器会根据协议类型自动决定使用
哪个端口. 例如 http 协议默认使用 80 端口, https 协议默认使用 443 端口.- /personInf/student : 带层次的文件路径.
- userId=10000&classId=100 : 查询字符串(query string). 本质是一个键值对结构. 键值对之间使用
& 分隔. 键和值之间使用 = 分隔.- 片段标识: 此 URL 中省略了片段标识. 片段标识主要用于页面内跳转
GET https://www.baidu.com/ HTTP/1.1
- GET为HTTP方法,描述了这个HTTP请求的作用,HTTP协议有很多方法,不同的方法有不同的作用.
GET的作用,是从服务器里面拿东西;POST是向服务器李提交东西.- www.baidu.com就是URL地址.
- HTTP/1.1表示HTTP的版本号.
关于 query string(查询字符串):
- query string 中的内容是键值对结构. 其中的 key 和 value 的取值和个数, 完全都是程序猿自己约定的. 我们可以通过这样的方式来自定制传输我们需要的信息给服务器.
- query string的参数一般是键值对结构,使用&分割键值对,使用 = 分割键和值.
- query string的作用是对请求资源进行细节的补充.
URL 中的可省略部分:
- 协议名: 可以省略, 省略后默认为 http://
- ip 地址 / 域名: 在 HTML 中可以省略(比如 img, link, script, a 标签的 src 或者 href 属性). 省
略后表示服务器的 ip / 域名与当前 HTML 所属的 ip / 域名一致.- 端口号: 可以省略. 省略后如果是 http 协议, 端口号自动设为 80; 如果是 https 协议, 端口号自
动设为 443.- 带层次的文件路径: 可以省略. 省略后相当于 / . 有些服务器会在发现 / 路径的时候自动访问
/index.html- 查询字符串: 可以省略
- 片段标识: 可以省略
关于 URL encode
- 像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.
比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.- 一个中文字符由 UTF-8 或者 GBK 这样的编码方式构成, 虽然在 URL 中没有特殊含义, 但是仍然需
要进行转义. 否则浏览器可能把 UTF-8/GBK 编码中的某个字节当做 URL 中的特殊符号.- 转义的规则如下: 将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式
“+” 被转义成了 “%2B”
urldecode就是urlencode的逆过程;
我们在查询C++关键字的时候,会惊喜的发现一个%2B
- http请求方法有很多,但是常用的有GET与POST两种,其余方法也可能出现,但是这两者经常用.
- 请求一般看到的是GET.
- 用到POST右什么呢?登录与上传文件的时候.
- GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源.
- 在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求.
- 另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求.
GET 请求的特点:
- 首行的第一部分为 GET
- URL 的 query string 可以为空, 也可以不为空.
- header 部分有若干个键值对结构.
- body 部分为空.
网上有些资料上描述: get请求长度是有限制的 这样的说法是错误的.
- HTTP 协议由 RFC 2616 标准定义, 标准原文中明确说明: “Hypertext Transfer Protocol HTTP/1.1,” does not specify any requirement for URL length. 没有对 URL 的长度有任何的限制.
- 实际 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现. 在浏览器端, 不同的浏览器最大长
度是不同的, 但是现代浏览器支持的长度一般都很长; 在服务器端, 一般这个长度是可以配置的.
有些资料上还说,POST比GET更安全…
这种说法也是非常错误的,安不安全取决于是否加密,而不是所采用的传输方法.
- POST 方法也是一种常见的方法. 多用于提交用户输入的数据给服务器(登陆页面).
- 通过 HTML 中的 form 标签可以构造 POST 请求, 或者使用 JavaScript 的 ajax 也可以构造 POST 请求
POST请求的特点:
- 首行的第一部分为 POST
- URL 的 query string 一般为空 (也可以不为空)
- header 部分有若干个键值对结构.
- body 部分一般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由header 中的 Content-Length 指定.
面试题: 谈谈 GET 和 POST 的区别:
- 其实,二者没有本质的区别,POST能实现的功能,GET也能实现;GET实现的功能,POST也能实现.在细微之处,二者还是有区别的.
- 语义不同,GET 一般用于获取数据, POST 一般用于提交数据.
- GET 的 body 一般为空, 需要传递的数据通过 query string 传递, POST 的 query string 一般
为空, 需要传递的数据通过 body 传递.- GET 请求一般是幂等的, POST 请求一般是不幂等的. (如果多次请求得到的结果一样, 就视为请
求是幂等的,也可以理解为输入的内容相同,你就会提前知道得到什么结果).- GET 可以被缓存, POST 不能被缓存. (前提情况也是幂等).因为可以被缓存,那么GET请求可以被浏览器收藏,POST不能被浏览器收藏.
小结一下:
- 语义: GET 完全可以用于提交数据, POST 也完全可以用于获取数据.
- 幂等性: 标准建议 GET 实现为幂等的. 实际开发中 GET 也不必完全遵守这个规则(主流网
站都有 “猜你喜欢” 功能, 会根据用户的历史行为实时更新现有的结果.- 安全性: 有些资料上说 “POST 比 GET 请安全”. 这样的说法是不科学的. 是否安全取决于
前端在传输密码等敏感信息时是否进行加密, 和 GET POST 无关.- 传输数据量: 有的资料上说 “GET 传输的数据量小, POST 传输数据量大”. 这个也是不科学
的, 标准没有规定 GET 的 URL 的长度, 也没有规定 POST 的 body 的长度. 传输数据量多少, 完
全取决于不同浏览器和不同服务器之间的实现区别.- 传输数据类型: 有的资料上说 “GET 只能传输文本数据, POST 可以传输二进制数据”. 这个
也是不科学的. GET 的 query string 虽然无法直接传输二进制数据, 但是可以针对二进制数据
进行 url encode.
- PUT 与 POST 相似,只是具有幂等特性,一般用于更新
- DELETE 删除服务器指定资源
- OPTIONS 返回服务器所支持的请求方法
- HEAD 类似于GET,只不过响应体不返回,只返回响应头
- TRACE 回显服务器端收到的请求,测试的时候会用到这个
- CONNECT 预留,暂无使用
- header 的整体的格式是 “键值对” 结构.,每个键值对占一行,键值对之间使用分号隔开,键和值之间使用冒号空格来分割.
- 这里的键值对可以有很多行,还会使用空格作为结束标记(相当于单链表末尾的NULL).
- header中的键值对,大部分都是HTTP协议规定的,也有一部分是程序员自己定义的键值对.
- 表示服务器主机的地址和端口.
- Host:www.baidu.com
这里的属性描述了浏览器这个请求要访问的服务器是谁,这里可以写地址,也可以写端口号.
在URL中,已经写了访问的服务器是哪一个,为什么在Host里面还要再写一遍呢?
- 一般而言,URL的域名和Host中的值是相同的.但是当我们在访问服务器的时候,不是直接访问,而是通过相关代理来访问的(这个代理不是指fiddler,而是其它的代理),这里时候,URL的域名和Host的值可能就不同了…
- URL可以表示当前位置,Host表示最终位置.Host可以确认是否到达了最终位置.
表示 body 中的数据长度,单位是字节.
表示请求的 body 中的数据格式.
- application/json : 描述了数据是按照json的格式组织的.
- charset=utf8 描述了数据的字符集是哪种.
Content-Type作为请求时的常见写法:
- json格式.
- form表单格式.
Content-Type作为响应时的常见写法:
- text/html
- text/css
- application/JavaScript
- application/json
- image/jpg
- image/png
- User-Agent (简称 UA),表示浏览器/操作系统的属性.
- UA在请求中告诉网站自己上网的设备是什么,此时,服务器就可以根据客户端的种类返回不同的属性信息.
- 随着网络技术飞速发展,各个浏览器之间的区别非常小了,UA也就没有那么重要了.
- UA目前一个重要的作用是区分用户是手机/PC/平板
UA能做到区分,但是却不常用.CSS3中提供了"媒体查询"功能,可以根据浏览器窗口的大小设置不同的样式,这种页面开发称为响应式布局(简单了解即可)
- Referer表示这个页面从哪个页面跳过来的.
- 直接在地址栏中输入url或者直接点击收藏夹是没有referer的,因为这两种方式不能表示从哪个页面跳转过来的.
Cookie
简而言之就是一种身份标识,相当于身份信息.- 我们可以理解为医院挂号看病,Cookie可以理解为我们的身体信息卡,记录了我们一些信息.
- Cookie也是采用键值对的形式,每个键值对代表什么意思呢?我们不得而知,因为这些都是程序员自己定义的内容,只有他们自己知道.
- Cookie的本质是浏览器在本地存储,用户自定义数据的一种关键机制.
往往浏览器也需要存储一些数据,经常会存储用户的身份信息,比如记住我们的登录账号和密码,方便我们下次快速登录.
怎么存储身份信息呢?
- 直接存储在硬盘上可以吗?这个当然是不可以的,如果允许网页能够操纵你电脑上的文件,这个时候你不小心点到了木马网站,此时,你的电脑很可能被入侵.
- 因此呢!为了保证用户上网安全,浏览器会做出限制,禁止网页能直接访问硬盘.
- 浏览器虽然禁止了直接访问硬盘,但是浏览器提供了Cookie机制,允许网页在浏览器中存储一些自定义的键值对,这些数据通过浏览器提供的api写入指定的文件中.
- 网页有很多种,比如百度,360,搜狗等.这么多网页我们怎么存储身份信息呢?针对这种情况,我们分开存储身份信息,每个网页存储自己的Cookie(按照域名进行存储),同一个网站共享同一份Cookie,不同的网站都有各自的Cookie.
Cookie怎么诞生:
Cookie是从服务器诞生的,当我们在访问服务器的时候,服务器就会在HTTP响应中,通过Set-Cookie字段中,把Cookie的键值对返回给浏览器,浏览器收到这个数据后,就会在本地存储.
Cookie要去哪
- Cookie会在下次请求的时候发送到服务器,服务器进行处理识别.
- Cookie在浏览器这边只是暂存,服务器来让Cookie真正发挥作用.
Cookie的作用:
- Cookie是浏览器本地存储数据的机制.
- Cookie存的数据不一定是账号密码,也可能是其它信息,只要是字符串都可以存储.
- Cookie的存储空间是有限的,不会使用Cookie存储太大的数据.
- Cookie最典型的作用是存储账号和密码.
- 一个服务器会和许多客户端进行交互,那么多客户端是如何区分呢?就是通过Cookie进行区分.客户端在登录的时候,服务器识别号客户端的Cookie,把客户信息返回给浏览器,在Cookie中进行保存,下一次客户端访问服务器的时候,拥有这个Cookie进可以直接进行访问(服务器根据这个Cookie识别客户端).
http请求正文就是body内容,在这里我们先简单了解一下,等我们学到前后端交互再进行详解.
- 请求正文中主要包含用户提交的参数信息.
- 参数由前后端提前约定好,后端服务器根据所传参数做相应的业务处理.
请求体常用的有两种,这两种都属于请求体,Content-Type不同,所使用的也不同.
- FormData
- RequestPayload
- 如果请求头中Content-Type为application/json,那么请求参数会以json格式传递,显示为RequestPayload.
- 如果请求头中Content-Type为x-www-form-urlencoded或multipart/form-data,那么请求参数会以&分割的格式传递,显示为FormData.