目录
认识HTTP协议
用Fiddler来分析HTTP协议的细节
抓包工具的原理
抓包的结果
HTTP请求
认识请求行
认识URL各部分内容
URL encode/decode
方法
GET方法和POST方法有什么区别(经典面试题)
认识请求“报头”(header)
Host
Content-Length
Content-Type
注意
UA(User-Agent)
Reference
Cookie
认识请求正文“body”
HTTP响应
认识状态行
版本号
状态码和状态描述
认识响应报头(header)
Content-Type
实现简单的HTTP代码
基于HTML实现HTTP请求
用GET方法
用POST方法
基于jQuery的ajax实现HTTP请求
1.HTTP协议(全称为“超文本传输协议”),是一种应用非常广泛的应用层协议。
2.HTTP往往是基于传输层的TCP协议实现的(HTTP1.0,HTTP1.1,HTTP2.0都是基于TCP实现的,HTTP3.0基于UDP实现),在使用中HTTP1.1最为热门。
3.模拟一个HTTP请求和HTTP响应的例子:
4.HTTP协议是一个文本格式的协议,可以通过抓包工具(Fildder)来分析协议细节。下面介绍Fildder的具体使用。
Fiddler相当于一个“代理”,浏览器访问sougou.com时,会把HTTP请求先交给Fiddler,Fiddler再把请求交给sougou服务器。当sougou服务器返回数据时,Fiddler拿到返回的数据,再把数据交给浏览器。
抓包的各块内容的含义:
1.HTTP请求:
首行(请求行):方法+URL+协议版本
Header(请求报头):请求的属性,每组都是用冒号隔开的键值对形式。
空白行:表示Header(请求报头)结束。
Body:空白行之后,允许为空字符串 ,如果存在Body,则在Header当中存在一行Content-Length属性来表示长度。
2.HTTP响应:
首行:HTTP版本号+状态码+状态码效果
Header(响应报头):请求的属性,每组都是用冒号隔开的键值对形式。
空白行:表示Header(响应报头)结束。
Body:空白行之后,允许为空字符串 。内容为服务器返回给客户端的数据。可能有各种不同的数据格式,典型的为html。
URL(Uniform Resour Locator统一资源定位符),互联网当中每个文件都有唯一的URL,它包含的的信息是文件的位置及浏览器怎么处理它。
1.协议方案名:描述了当前这个URL是哪个协议来使用的,http:// 给HTTP协议使用的;https:// 给HTTPS协议使用的。jdbc:mysql:// 表示给jdbc:mysql来使用的。
2.登录信息(认证):这部分当今很少用到,在久远的时间之前,这部分是用来体现用户名和密码的。
3.服务器地址:当前要访问的主机,这里可以是一个IP地址,也可以是一个域名。
4.服务器端口号:表示当前要访问的主机上的应用程序,端口号大部分情况下是可以省略的。省略的意思是:不需要手动写一个端口号,而是浏览器会自动赋予一个默认值。http开头的URL会赋予端口号80作为默认值;https开头的URL会赋予端口号443作为默认值。
5.带层次的文件路径:描述了当前要访问的服务器资源是啥。虽然URL上写着一个具体的文件路径,但在服务器上不一定存在一个对应的文件,也可能是虚拟的,由服务器的代码构造出来的一个动态数据。
6.查询字符串:本质上是客户端/服务器给服务器具体文件传递的一个自定义信息。相当于对获取到的资源做进一步的要求。查询字符串的内容本质上也是键值对结构,多个查询字符串直接用&相隔。查询字符串和带层次文件路径之间的?起到了相隔的作用。
7.片段标识符:描述了当前要访问html页面中的哪个具体子部分,能够控制浏览器滚动到相关的位置。
1.当query string(查询字符串中的键值对)中包含了特殊字符,就需要对特殊字符进行转义,这个转义的过程就叫url encode,把内容还原回来就是url decode。
2.url里面有很多特殊含义的符号,如/ : ? & = …… ,如果这些字符出现在query string当中,就可能导致URL解析失败。
3.URL endoce的转义原理:当用搜狗搜索C++时候URL中的query string 会出现
其中的两个%2B就代表了两个+,而2B是十六进制43,所以就是将+的ASCII(二进制)转化为十六进制再加上%。
HTTP协议中的方法非常多,但是最常用的就是GET 和 POST方法;在使用频率上GET占80%,POST占10%,剩下的方法占10%。
盖棺定论,GET方法和POST方法没有本质上的区别。(在一些场景中,GET方法能替换成POST方法,POST方法也能替换成GET方法)
1.语义上的区别。GET方法通常用来获取数据,POST方法通常用来上传数据。但是现状是,GET也经常用来上传数据,POST也经常用来获取数据。
2.通常情况下,GET是没有body的,通过query string向服务器传递数据;POST是没有query string的,但是有body,通过body向服务传递数据。
3.GET请求一般是幂等的,POST请求一般是不幂等的。(幂等指的是每次输入相同的请求时,得到的输出结果是相同的;不幂等指的是每次输入相同的请求时,得到的输出结果是不相同的。)
4.GET请求的结果可以被缓存,POST请求返回的结果不能被缓存。如果结果是幂等的,那很可能会缓存。
header里面也是一些键值对,不同的键值对有不同的含义,下面介绍键值对代表的重要含义。
表示服务器的主机地址和端口,域名可以通过DNS转化为IP地址。
表示了body数据的长度。
表示的是请求body中的数据格式。
常用的Content-Type有三种:
1.
2.
3.
1.上述两种属性都是描述body的,如果请求当中没有body(GET),也就不需要这两个字段了。
2.会衍生出一个问题,为什么我们登录的时候一般是使用POST请求的?
答:其实使用GET请求也是完全可以的。不过因为GET请求没有body,使用账号和密码都会被集中体现在URL的query string当中,此时会出现浏览器上方地址栏出现一大段路径,导致用户体验不良。相反POST请求没有query string 有body,用户输入的账号和密码等内容会记录在不会直接体现在用户使用界面的body中,这样很大程度地提升了用户的体验,因而会选择基于POST请求实现登录。
3.在上述的背景下,也会出现一种错误的认识:基于POST实现的登录比基于GET实现的登录更加安全。正确的观点是:用户账号和密码的安全问题,取决于是否是明文传输,如果基于GET请求加密传输是安全的,同样的基于POST的明文传输是不安全的。
4.HTTP是基于TCP实现的协议,TCP是一个面向字节流的协议,会存在粘包问题,需要通过设计应用层协议来明确包和包之间的边界,可以使用分隔符和长度,这在HTTP中也有体现。
当若干个GET请求到达TCP缓冲区后,应用程序读取请求时,会使用空行作为分割符,因为GET请求当中没有body。
当若干个POST请求到达TCP缓冲区后,应用程序地区请求时,会利用长度(Content-Length)来明确边界。
1.这个字段表明用户当前使用什么设备上网。
这其中的数据分别表示:当前技术标准的版本,当前计算机操作系统版本,使用的浏览器名称。
2.这个字段出现的原因是,在久远的年代,浏览器的性能和参差不齐,使用的标准没有统一,存在老旧浏览器加载不了新页面的问题。这时候,UA字段就起到像服务器“自报家门”的作用。但是,在当今浏览器都发展完全,标准统一的时代,UA指责依旧还在,主要用于区分PC端和移动端。
1.这个字段是用于服务器区分当前页面是从哪个页面跳转过来的。
2.Reference这个字段的应用也是非常广泛的。在广告投放的过程中,广告主和提供广告的公司会同时记录用户访问广告主页面的来源,以便后续计算费用。提供广告公司的记算方式是:在服务器计数跳转到到达广告主页面的次数;广告主的计算方式是:观察请求的Reference栏是哪个域名跳转来的。
1.Cookie出现的背景:浏览器为了安全默认使得网页上的JS不能访问计算机磁盘上的文件,假设一个网页存在恶意的代码,如果没有安全防护机制,会触发恶意代码导致计算机文件遭破坏。有了这样的安全机制,也会带来一些麻烦:当用户访问页面需要一些持久化存储的内容时,会出现不便。其中最典型的就是用户需要存储一些身份验证信息,方便后续访问页面带来便利。逐渐的,出现了Cookie来存储用户的验证信息。
2.Cookie的原理:是浏览器给页面提供的一种持久化存储数据的机制,持久化存储数据不会因为浏览器或主机重启而丢失,即存储写入磁盘当中。当今,有很多种功能和Cookie相似的机制出现,Cookie作为一种经典的方式,应该优先学习这种方式。
3.,Cookie具体的组织形式:先按照域名来组织,针对每个域名在浏览器分配一定的空间,访问百度,就会给百度分配Cookie,访问码云,就会给码云分配Cookie。具体在浏览器当中可以显示:
存储形式:键值对的存储方式,名称和内容分别代表键和值。
4.Cookie的运作方式:
在客户端HTTP请求的header当中存在Cookie键值对,用于完成身份认证,和服务器建立连接。
连接后,服务器会给客户端返回一些具体的信息,以Set-Cookie这样的响应报头来表示:
5.session
像这样存储在计算机磁盘上的数据还是具有丢失的风险,所以最好的存储这种数据的方式还是存储在服务器的上,存储这样的数据的空间称为session会话,服务器上有许多这样的session,每个session存储用户的关键信息,每个session也有专属的sessionId。
请求正文的内容和header中的Content-Type相关,常用的有以下三种:
1.application/x-www-form-urlencoded
2.multipart/form-data
3.application/json
这一块写的是浏览器所使用的HTTP的版本号。
状态码的含义是这次请求的结果是怎么样,加上状态码代表的意思。有很多种状态码,最常用的有以下几种:
1.200 OK:浏览器很顺利就获取到想要的内容。
2.404 Not Found:要访问的资源不存在。
3.403 Forbidden:虽然权限有,但是你没有访问的权限。
4.405 Method Not Allowed:这个情况在外面的抓包很难碰到,这个状态码的意思是,用GET请求而目标服务器要求的方法是POST,这时就会返回状态码405。所以这种情况只有在个人实现的后端服务器才会遇到。
5.500 Internet Server Error:这个状态码的意思是当前访问的目标服务器出现故障。同样的,这种情况在个人实现的后端服务器比较常见。
6.302 Move temporarily:重定向,在登录过程中常会出现,表示跳转的发送。location后面接的是要跳转到的目标地址。
最常见的几种状态码:
2开头表示成功的;
3开头表示重定向;
4开头表示客户端出现错误;
5开头表示服务器出现错误。
请求报头和响应报头的格式基本相同,类似于Content-Length和Content-type等属性的含义也相同。
有如下几种常用的格式:
text/html:body格式是html;
text/css:body格式是css;
application/javascript:body的格式是javascript;
application/json:body的格式是json。
能够通过代码实现HTTP请求,一般客户端是实现HTTP请求的一方,浏览器就是长江的客户端。
所以一般采用HTML和Javascript这两种前端语言来实现HTTP请求,下面会分别介绍这两种构造情况。
基于HTML的核心就是采用标签的方式,最主要利用的也就是其中的form标签。
这其中action后面接的是一个URL,代表的是要提交请求的服务器。后面的method则代表提交的请求类型,如果用get类型的请求,参数会放在query string当中;如果是post类型的请求,参数会放在body当中。具体差异如下:
参数会在请求行的query string当中以键值对的形式表现出来,键和值用=隔开,每个键值对之间用&隔开。
参数放在body当中,也以键值对的形式体现出来,键和值用=隔开,每个键值对之间用&隔开。
基于ajax实现的HTTP请求对比基于HTML实现的HTTP请求有一个明显的优势,不同与基于HTMLform实现的HTTP请求在页面加载过程中会将所有内容都给加载出来,基于ajax实现的HTTP请求在页面加载更加灵活,通过js代码来构造出HTTP请求,再通过js代码来处理HTTP响应,以回掉函数的方式处理响应并把得到的数据加载到页面上。为异步式等待。
等待分为三种:
1.同步阻塞等待:一直等待响应,期间不能完成其他的工作。
2.同步非阻塞等待:等待期间可以完成其他的工作,但需要多次查看是否响应。
3.异步等待:等待响应期间可以完成其他的工作,且不需要查看响应。
在通过控制台输入/输出,通过文件输入/输出,网络输入/输出等IO操作时,会经常涉及到这三种情况。
先在本地文件引入jquery.api,再在HTML中的script标签当中完成js语言的输入。
结果虽然发送请求能够成功,但接收不到响应。
原因是:ajax禁止进行跨域访问,跨域访问指的是跨越多个服务器/多个域名,当前处在的服务器是本地文件,页面ajax的url是搜狗的服务器,这就算跨域名访问。那么怎样才算不是跨域名访问:当前的服务器上www.sogou.com,ajax的url域名为www.sougou.com这样就不算跨域名了。具体实现等创建完服务器在进行介绍。