目录
二、Content-Length / Content-Type
前言
HTTP是应用层最典型协议,为什么这么说?看看他的应用场景:
- 绝大部分的浏览器与服务器的交互;
- 绝大部分手机APP与服务器交互;
- 服务器之间相互调用也可以使用HTTP;
即使最新的HTTP版本已经3.0了,但本文重点介绍1.1版本;
对HTTP协议总体的一个认识:
一、HTTP协议是什么?
HTTP是前后端交互的桥梁,是最典型的“一问一答”的模型协议,HTTP协议主要用于用于Web浏览器和Web服务器之间的通信,想要学习一个协议,主要就是学习HTTP的报文格式;
例如:当你在浏览器的地址框中输入一个URL或是单击一个超级链接时,URL就确定了要浏览的地址。浏览器通过超文本传输协议(HTTP),将Web服务器上站点的网页代码提取出来,并翻译成最后看到的网页。
构造一个HTTP请求本质上就是往TCP socket中,按照以下将要讲的格式来写入数据即可;
1.1、HTTP请求格式(以百度网页为例)务必要掌握~
1.2、HTTP响应格式
对HTTP协议具体的一个认识:
一、什么是URL
URL就是我们实际输入的网址,也叫“唯一资源定位符”,他就像门牌号一样,通过他就可以在服务器中找到我们需要访问的资源;
1.1、URL格式
- 协议方案名:常见的有http和https,https实际上就是http加密后的协议;
- 登录信息:现在的网页进行身份认证不通过URL了,所以可以省略;
- 服务器地址:就是服务器的IP地址,也可以写成域名;(域名和IP地址是等价的,域名是方便用户认识产生的一种形式,通过DNS域名解析系统,就可以将域名转化成IP地址发送给服务器)
- 服务器端口号:标识了要访问的目标服务器是哪个进程;
- 带层次的文件路径:服务器上的文件路径(这个路径就描述了展示网页所需要的资源的位置在哪),HTTP服务器一般不会把电脑上所有资源都提供到网页上,通常是指定某个目录为根目录,这个目录里的内容,才是用户可以访问的;如果这些内容是服务上真实的文件资源,那么就叫做——访问静态资源;若是HTTP服务器没有访问真实数据,而是在内存中构造出的HTML,返回到浏览器,这叫做——访问动态资源;
- 查询字符串:前面是一个问号,后面跟一个键值对结构(完全是程序员自定义的)键值之间通过&分割,称为query string,浏览器给服务器传递的必要参数;
可以将URL形象成这样一个东西~(如下)
http://门头沟学院3号餐厅:65号窗口/麻辣烫?口味=香辣&是否加香菜=多放点&是否放蒙汗药=多放点&几套餐具=3
1.2encode / decode
把原始字符转义后的字符就是 URL encode(编码);
把转义后的字符还原成原始的字符就是 URL decode(编码);
例如一段搜狗的网址
这里用%分割开的实际上就是个十六进制数字,将他通过ascii码表进行翻译,就可以知道他要表示的内容了~
二、HTTP协议中两个重要方法
2.1、GET
GET是HTTP请求最常用的方法,本质上就是浏览器通过GET方法,向服务器发起GET请求,从服务器拿到相应的数据;
什么时候会触发这个请求?
1.浏览器的地址栏中输入URL,就会触发GET;
2.HTML里的link、a、img、script会触发GET请求;
3.html中的form标签可以构造出GET请求;
4.使用 JavaScript 的 ajax 也可以构造 POST 请求
很多人的误区:“GET请求长度长度最多是1KB / 2KB …?”;这个说法真的正确吗?
HTTP 协议由 RFC 2616 标准定义, 标准原文中明确说明: “Hypertext Transfer Protocol — HTTP/1.1,” does not specify any requirement for URL length.
也就是说,标准中,并未对URL的长度做出限制;其实虽然没有提到有长度上限,但是浏览器和HTTP服务器在实现的时候,可能有长度上线,也可能没有,具体要看如何实现了;
2.2、POST
POST是用来将用户输入的数据发送给服务器的一种方法;(例如一些网站的登录界面,当你输入账号和密码,提交以后,便会执行这个方法);
什么时候会触发这个请求?
1.通过 HTML 中的 form 标签可以构造 POST 请求
2.使用 JavaScript 的 ajax 也可以构造 POST 请求
POST请求的特点:
1.POST请求中,首行第一部分为POST;
2.URL一般没有query string;
3.header 部分有若干个键值对结构.
4.body部分的数据格式有很多种,一般不会为空;
2.3、常考面试题——谈谈GET和POST的区别?
第一步、直接盖棺定论:
GET和POST没有本质区别,使用GET的场景基本都可以使用POST代替,使用POST的场景也可以用GET代替;
第二步、谈细节上的区别:
细节一:(语义上)
GET语义:从服务器获取一个数据;
POST语义:往服务器提交一个数据;
虽然HTTP协议说是这么说,但是很多程序员还是没有遵守这个约定~
细节二:(使用习惯上)
习惯上,给服务器传递数据,GET通常放在URL的query string中,POST通常是放在body;中;
GET能放在body中吗?可以滴,HTTP客户端支持,但是浏览器不一定支持;
POST能放在query string中吗?可以呢!浏览器和客户端都支持~
细节三:(幂等)
GET请求建议实现成“幂等”的,POST不做要求;(幂等简单来说就是,输入是确定的,输出也是确定的);
服务器设计时会提供一些api:api传入的参数视为输入,返回的结果视为输出;基于GET的api建议设置成幂等的,POST不做要求;
细节四:(缓存)
在幂等的基础上,GET请求结果是可以被缓存的,POST一般不缓存;
这时浏览器默认的,若当前GET时幂等的,就不做处理,让浏览器缓存;若当前GET不是幂等的,就需要通过特殊技避免产生缓存;(技巧就是让GET请求的URL都不同,通过特殊的query string保证URL不同);
POST比GET更安全,这个说法正确吗?
虽然在登录界面GET把参数放到的URL中确实不好,但是放到POST的body中,也一样没有更安全;因为咱们平时谈到的是否安全,是指:你的数据被黑客截获后,会不会对你造成信息泄漏这样的影响,只要你的代码没有进行加密,就谈不上安全;
HTTP协议中的请求头(header)
一、Host
表示服务器主机的地址和端口(要去哪才能找到服务器), 这里端口号可以省略,若省略,则使用默认值;(HTTP的默认值是80,HTTPS的默认值是443)
问题一:URL里的IP和端口号和Host有区别吗?
有区别,URL的IP和端口和Host有可能一样,也有可能不一样,当请求是经过代理来访问的时候,可能会不一样(以上截图是博主通过Fiddler抓包截下来的,然而以上结论在Fidder没有体现出来);
为什么?如下图情况:
二、Content-Length / Content-Type
这两个字段不一定有,但若有一个,就会有另一个;具体看是否存在body;
2.1、Content-Length
表示body中的数据长度;
Content-Length有什么用呢?
HTTP协议,在传输层是基于TCP(HTTP3.0之前是这样,3.0就是UDP了),而TCP是面向字节流的,那么就会存在粘包问题~ 如何解决呢?1.约定一个分隔符;2.约定报文长度;这时Content-Length确定了body数据的长度,就可以很好的解决粘包问题~
2.2、Content-Type
表示请求的body中的数据格式;
Content-Type有什么用呢?
body中的数据可以是很懂中格式,不同的格式对于接收方来说,解析方式是截然不同的;可能会有的格式例如:form表单构造的请求、query string的键值对格式、以及json格式…
三、User-Agent(简称:“UA”)
简而言之:UA主要包含的就是“操作系统信息”和“浏览器信息”,描述了用户在使用什么样的设备上网;
User-Agent 有什么用呢?
在互联网不发达的时候:通过UA手机浏览器/操作系统信息,就知道该支持什么页面了;若是一个原始的浏览器,就返回一个纯文本页面,若是一个先进的浏览器,就返回一个功能丰富的页面(这样做是为了考虑兼容性);//这些都是2015年左右的问题,现在以及不是问题了,那UA就没用了吗?当然不会,往下看~
在互联网发达的时候(当今社会):可以根据UA识别出PC、平板、手机,分别开发不同版本的页面;(UA确实削弱了,但至少还可以用在服务器统计用户的设备情况~);
四、Referer
表示当前页面是从哪个网页跳转过来的,若在浏览器地址栏直接输入一个地址,或是直接点击收藏夹,就没有referer;
如下图:(从百度搜索minecraft,Fiddler捕捉到的Referer就是百度的网址)
什么?你问我有什么用?
哈哈,在浏览器里贴小广告,统计是哪个浏览器被用户的点击了,并记录点击次数;这有什么用?赚钱啊哈哈哈,开发浏览器的公司自己统计一次,广告商自己统计一次,最后对比看没问题,就会像浏览器结算广告费~ 什么小广告?就是下图这样的小广告~
五、Cookie
有时候需要让网页存储一些简单数据,但由于网页禁止js访问电脑硬盘(原因:安全性),所以就提供了特殊的api给网页用,Cookie就是最经典的一个方案,是浏览器在本地存储数据(存储到硬盘上)的一种机制;
Cookie如何组织信息的?键值对的形式!(如下图)
Cookie是用来存放什么数据的?
- 上次访问网页的时间;
- 当前网页的访问次数
- 当前访问网页网页的身份标识(最典型的应用场景);
特点:
- Cookie是按照域名维度来组织的,不同域名下有不同的Cookie;
- 和query string一样,是程序员自定义的;
- 每一个Cookie都是一个键值对;
- Cookie有个过期时间,到时自动清除;
注意:Cookie不是缓存,是持久化数据的手段(保存在硬盘上),缓存的数据是用来提高访问速度的;
5.1、Cookie从哪里来?
Cookie存在于浏览器,来源于服务器;
解释:在网页中我们所观察的Cookie都是浏览器访问了某一个服务器后,服务器返回一个响应报文,在响应header中包含 一个/多个 Set-Cookie这样的资源(程序员自己在服务器代码中写的),浏览器接收响应后,就见Set-Cookie这样的数据保存到浏览器本地;
如下图Fiddler所捕捉到的Set-Cookie:
5.2、Cookie到哪里去?
来自服务器,存储到浏览器,最后返回到服务器;
解释:当浏览器保存了cookie后,下次访问同一网站,就会把之前存在本地的Cookie作为身份标识在http请求的header给返回到服务器,服务器就知道,喔,又是你来了~就把上次加载好的数据作为响应返回给浏览器;
5.3、Cookie 典型应用场景——维持登录状态
在某网站上成功登录后,浏览器会记住当前登录用户的身份信息,接下来再访问该网站的其他页面时,服务器也能知道是谁在登录;
具体解释:
HTTP响应中的状态码
一、状态码(重点)
状态码是一个数字,描述了当前请求的“状态”(成功、失败、失败的原因);
以下介绍几个常考的
1.1、404 Not found
这是一个常见的错误,问题的原因是因为请求路径写错了;
解释:请求中的url就是路径,表示你要访问的服务器上的资源,如果这个资源服务器上没有,就会返回404;
1.2、403 Forbidden
403就表示访问被拒绝,也就是没有权限访问;
事实上:状态码中以4开头的,都是客户端这边处了问题;
1.3、500 Internal Server Error
500表示服务器内部错误,服务器代码执行过程中,出现了异常;
1.4、504 Gateway Timeout
表示访问超时,一般在服务器请求量很大的时候,服务器符合比较重,就容易出现;
规律总结:服务器处理问题,一般就是5来开头;
1.5、302临时重定向
访问一个旧的URL,自动准一道新的URL上;
常见场景:
- 服务器地址迁移;
- 搜索引擎点击跳转;
1.6、状态码表参照
状态码类别 | 详情 |
---|---|
1XX | 信息,服务器收到请求,需要请求者继续执行操作 |
2XX | 成功,操作被成功接收并处理 |
3XX | 重定向,需要进一步的操作完成请求 |
4XX | 客户端错误,请求包含语法错误或无法完成请求 |
5XX | 服务器错误,服务器在处理请求的过程种发生了错误 |
如何构造一个HTTP请求?
一、通过前端构造的三种方法:
1.1、通过浏览器自己构造
工具:浏览器;
打开你的浏览器,在地址栏里写url,按下回车,就可以构造出get请求;(如下图)
1.2、通过form表单构造
工具:vscode;
步骤一:在vscode中,创建html文件,构造一个form表单;(具体的如下代码)
<body>
<form action="https://cn.bing.com/" method="get">
<input type="text" name="a">
<input type="text" name="b">
<input type="submit" value="提交">
</form>
</body>
解释:
- form表单的关键作用是传递键值对
- action是你选择的网页;
- method是构造http请求的方法,这里只支持 get 和 post ;
- input标签用来构造键值对数据,一个input的就是一个键值对,name表示“键”,用户输入的数据表示“值”,最后通过submit来提交,发送请求
- 若使用get方法,上述键值对就会存到url的query string中;若使用post方法,上述键值对就会放到body中(格式与query string一样);
步骤二:打开HTML网页,输入你想输入的值;(如下图)
最后:网页跳转,地址栏(如下图)
1.3、通过ajax构造
工具:vscode,jquery第三方库;
最初ajax主要是借助HTTP传输xml,现在xml用的少了,因此ajax往往用来传输其他数据,例如json;
form表单构造的数据一定会出发页面跳转,时间慢,开销大,所以并不是一件好事,使用ajax就可以不触发跳转,达到“局部刷新”的效果;
步骤一:ajax api是浏览器自带的,原生api不太好用,所以可以使用第三方库,代替原生api;打开jquery官网(js中最知名的第三方库之一),复制script链接;
步骤二:输入以下代码;
<script src="https://lib.baomitu.com/jquery/1.12.4/jquery.min.js"></script>
<script>
$.ajax({
type: 'get',
url:'https://cn.bing.com/',
success: function(body) {
//服务器返回正确响应(状态码:200),浏览器就会调用这个函数,处理响应;
//参数body就是响应的正文
console.log("OK~");//打印日志
},
error: function() {
//服务器返回一个错误响应,浏览器就会调用error对应的函数
console.log("error~");//打印日志
}
})
</script>
解释:
- 第一个script标签的src属性里的url就是刚刚从第三方库中所获取的;
- type表示使用get方法;
- url表示选择的网页;
- success表示当服务器返回正确响应(状态码:200),浏览器就会调用他对应的函数,处理响应;参数body就是响应的正文;
- error表示服务器返回一个错误响应,浏览器就会调用error对应的函数;
最后:打开html,打开调试,会观察到如下信息:
解释原因:
这里出错了;原因是跨域(一个页面在域名a下通过ajax访问域名b的资源),这里浏览器是禁止的,除非跨域的网站返回的响应中告诉浏览器可以;(大部分网站是不可以的);
解决方法:
这里我们可以自己写一个服务器,把页面放到自己的服务器上,让页面访问自己服务器的资源;(这里不展开讲,后期会出博客);
二、通过postman构造
工具:
属于是一个专门构造HTTP请求的第三方工具,主要是帮助接口测试的,简而言之:它可以用来更方便的构造HTTP请求;
具体步骤如下图:
最后结果:
三、通过Postman生成各种语言HTTP请求
具体步骤如下图: (简直不要太爽~)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/124309.html