1)当我们在浏览器上面输入一个搜狗搜索的网址之后,浏览器就会给搜狗的服务器发送了一个HTTP请求,这样咱们的搜狗的服务器就会返回一个HTTP响应;
2)当这个响应结果被浏览器解析之后,就展示成了我们目前所看到的页面内容,这个过程中咱们的浏览器可能会给服务器发送多个HTTP请求,服务器会返回多个响应,这些响应里面就包含了HTML,CSS,JavaScript,图片和字体等信息;
一)HTTP协议中常见的请求方法:
1)DELETE:删除服务器指定资源;
2)OPTIONS:返回服务器所支持的请求方法
3)TRACE:追踪路径
4)CONNECT:要求用隧道协议连接代理
5)HEAD:类似于GET,只返回响应头,不返回响应尾;
6)put方法:传输文件
7)unlink:断开连接关系
8)link:建立和连接之间的关系
GET 请求的参数会保存在历史记录中,而 POST 请求的参数不会保留到历史记录中;
一)不同种类的请求,就要用方法来区分,为了区分不同的语义,语义这就表示说有特定的含义,这是属于HTTP协议设定之初的一个初心,把请求根据功能划分成不同的类,随着时间的推移,这些方法已经失去了原有的意义,不同方法之间是可以替换的,进一步来说这些方法之间是没有本质区别的,理论上是可以相互替换的;
比如说h3,p,a,img标签就是语义化标签,但是div,span就是无语义标签
二)例如我们用GET向服务器里面来提交一个数据是否可以?用GET来删除数据是否可以?这些都是可以的,这不过这两个并不是常见用法,一切的一切都是取决于程序员的代码是如何实现的
三)咱们进行设计HTTP的大佬希望程序员可以按照HTTP的语义来进行使用这里面的各种方法,但是随着时间的推移,我们使用方法使用着使用着就开始走形了,基本上是全部使用的是GET/POST,基本没有考虑过语义的事情,也正因为这样咱们的HTTP请求中的很多方法之间的界限就开始变得模糊了;
GET和POST之间有什么区别?
都是基于TCP/IP协议来进行实现的,实用两者中的任意一个,都可以进行实现客户端和服务器端的双向交互,没有本质区别,但是在细节上还是有本质区别的//关键的一句话;
相当于是说咱们GET能够使用的场景,POST也是可以使用的,POST能够使用的场景,一个以替换成POST
1)数据位置:GET通常把自定义数据放到querystring中,POST通常把自定义数据放到body中,GET没有body数据,POST通过body发送数据;
2)语义区别:GET一般用于获取数据,POST一般用于提交数据
3)幂等性:GET请求一般是幂等的,POST请求一般是不会设成幂等的;
4)可缓性:GET请求一般会被缓存(常见的CSS,JS,HTML请求都会被缓存),POST请求一般默认不会缓存,这同样也是取决于程序员的设计,总而言之,这些东西都是可以被打破的,最终的结论还是一句话POST和GET没有本质区别;
5)GET请求的地址可以被收藏为书签,POST请求的地址一般不能收藏为书签;
1)那么什么时候会触发HTTP中的GET请求呢?
1)直接在浏览器中输入一个URL,就会触发HTTP的GET请求,例如我们在浏览器上面输入一个CSDN,服务器就会返回一个HTML界面;
2)HTML中的一些特殊标签,link(引入CSS)(页面加载时触发),img(图片),script(引入JS),a超链接(用户点击时会触发);
3)form表单,AJAX,自己写代码;
2)构建POST请求的方式也是非常多的:
1)form表单
2)ajax
3)第三方工具:POSTMAN
GET请求的特点:
1)首行的第一个部分是GET,URL中的querystring可以是空也可以不是空;
2)header中的部分由若干个键值对,而且他的body部分经常是空;
3)但是他的body部分也是可以不为空的;
POST请求的特点:
1)首行的第一个部分是POST
2)URL中的querystring一般为空,当然不是空也可以;
3)header部分有若干个键值对,
4)body部分一般不为空,当然如果是空,也是可以的,body里面的数据格式里面可以支持很多种格式,格式的类型,是由请求头中的Content-Type所决定,body的长度,是由请求头中的Content-Length来进行表示
什么是缓存?
1.1)比如说进行一些复杂的计算的时候,得到一些结果,但是如果说这个结果的计算过程代价太大,就可以把这样的结果保存下来,下次直接进行使用,避免进行重复的计算了,GET请求一般是要去要缓存的,POST请求一般是要求不用进行缓存的;
1.2)但是有一种特殊情况,在某些业务条件下,像搜索广告这种,虽然也是GET请求,但是绝对是不可以缓存的(每一个请求一定要是实时计算的);
1)咱们的缓存就是就是提前把结果记住,但是如果是幂等的,那么把结果记住是很有用的,这样子就节省了下一次进行访问的开销,但是如果是说不是幂等的,那么就不需要进行记住
2)如果请求本身都不是幂等的,那么就不可以缓存,比如说咱们获取到的广告数据虽然也是通过GET请求拿到的,但是绝对不能进行缓存,我们必须要进行实时的计算,我们必须要保证合适的用户出合适的广告,出的广告也是必须要符合广告主的规则,比如说周六不让有广告,但是某个用户在周六收到了广告;
什么是幂等呢?
幂等就是说每一次你进行了相同的输入,得到的输出结果就是确定的;
不幂等就是说每一次你进行了相同的输入,得到的结果就是不确定的;
1.1)这是数学上的术语,某个请求,执行一次和执行多次没有什么区别,如果可以做到这一点,就被称为幂等,例如支付宝里面有查看余额功能,就是幂等的,但是给客户转钱,转账功能,如果不加限制,就不是幂等的;
1.2)像这种转账操作,有时也是需要设计成幂等的,例如有时机器故障,导致服务器收到请求多次,导致进行多次转账,一个简单粗暴的方式就是,给每次转账,都分配一个唯一的身份标识,如果服务器收到很多的相同的身份标识,对其进行去重,那么只执行一次转账;
也就是说相同的HTTP数据包多次发送,不会影响客户端的结果;
GET请求的url:
协议名字+IP地址/域名+端口号+带层次的文件路径+查询字符串+片段标识符
定位到一台主机上面的一个唯一的服务器应用程序上面的资源,查询字符串就是针对这个资源做出了进一步的要求
二:请求报头:
请求的报头中里面的键值对是有很多的,这里面的键值对有些是标准规定的,不同的键值对还有不同的特殊含义,有些是用户自定义的,每个键值对都是独占一行的,键和值使用冒号分隔;
1)Host:这是来描述服务器主机的IP地址/端口号,地址可以是域名,也可以是IP,Host里面的东西,其实是和URL中的表示信息是重叠的,一般来说Host中的内容是和URL中的地址是一致的,但是也不是绝对的,因为咱们的域名是可以通过DNS服务器转化成IP地址的;
2)Content-length:表示Body的长度,单位是字节;
3)Content-Type:表示body中的数据格式的类型,告诉服务器要如何解析Body;
上面的这两个属性是在描述body的,如果说你的请求是一个GET请求,而你的请求报文里面没有body部分,也就说明此时不需要Content-Length和Content-Type这两个字段了,一般咱们的POST请求都是带body的;
因为咱们的HTTP协议在底层是一个应用层的协议,那么我们就有可能面对粘包问题
所以说我们要设计合理的应用层协议,来进行明确包和包之间的边界
1)使用分隔符
2)使用长度
1)比如说当前有若干个GET请求的数据包到达了TCP的接收缓冲区里面了,此时在HTTP协议里面,当我们的应用程序读取请求的时候,就以空行作为分隔符,遇到一个空行,说明一个数据包读取完毕,仅此而已,通过空行来作为结束标记
2)假设此时发送方发送了一堆POST请求,也就是一大堆TCP的数据包到达了接收缓冲区,因为咱们的POST请求是有body格式的数据的,此时当我们的应用程序读到了空行之后,就需要再次按照Content-Length的长度,再来进行读取若干个长度的数据;
咱们的登录为什么要使用POST来进行实现?
1)其实我们本质上是用GET方法也是可以实现登录的,但是你要进行登录,就必须需要给服务器来传递用户名和密码,如果是GET方法,用户名和密码通常会存放在URL上面的QueryString来进行传递,这个时候咱们的浏览器中地址栏里面的数据,就可能变得很长一串
2)这个时候用户体验很可能就会变得不算太好,因为早期的很多网站都是把密码变成明文提交的,如果说密码直接就出现在url里面,其实看起来就是非常的不好
3)咱们的POST请求时直接把数据放在body里面的,body中你进行存放什么样子的数据这些东西对用户的影响是非常小的,但是通常网上有一种说法说使用POST实现登录,是因为POST比GET实现登录更安全,这是典型的错误,因为是否安全,是取决你是否使用明文来进行传输,是否加密过;
请求报文里面的常见的ContentType:
1)application/x-www-form-urlencoded:
这是表单提交的数据格式,每个字段 键=值,此时body中的格式形如:title=test&content=hello;
1.1)键和值之间用=分割,键值对和键值对之间使用&来进行分割,出现%是因为urlencode方式的结果;
1.2)这里面的表单,就是HTML中的form标签,包括input,textarea这些标签都是可以搭配form来进行使用的,form的效果就是与服务器之间进行交互,能够构造出GET/POST请求;1.3)所以说咱们的POST请求的body中的application/x-www-form-urlencoded中的数据格式是和咱们的GET请求中的QueryString的键值对表示的方式是完全相同的;
二)上传文件的时候,multipart/form-data;bounday=....,表单提交的数据格式,在form标签上加上enctyped="multipart/form-data上传文件:
2.1)一般用于请求,不用于响应,其中每个字段可以是简单的数据类型(数值型,字符串,boolean值)
2.2)也可以是复杂的数据类型(图片视频等等)这就意味着form-data可以上传任意多的数据,也可以是多个文件
2.3)bounday表示边界,要传输的数据从哪里开始,到那里是结束
3)application/Json body按照Json数据格式来表示:
{"username":"123456789","password":"xxxx"}
4)image.jpg:指定一个具体的文件类型,如果客户端发送请求也就只能上传一个文件,如果用于服务器的响应,也就只能返回一个文件;
4)user-Agent:用来表示浏览器,操作系统的属性,简称为UA,现在是用来区分PC端和移动端;
1)在上古时期,那时候的浏览器还是比较简陋的,正在处于一个高速发展的时期,最早的浏览器只可以显示文字,不可以显示图片,更是不可以支持各种多媒体,随着时间的推移,就出现了一些浏览器能显示图片,再后来,有一些浏览器可以显示多媒体,再后来,有一些浏览器能够支持丰富的交互(支持JS交互,支持flash......);
2)浏览器的升级是一个逐渐的过程,早期并不是所有的浏览器既可以显示图片,又可以显示多媒体,又可以显示文字,这是程序员就不知道要返回一个什么样的页面,因为有的页面只支持文字,有的只支持图片;
3)这时就要让浏览器访问网站的时候,自报家门,告诉服务器我是哪个哪个浏览器的版本(UC),服务器就知道了这个浏览器支持那个功能,根据对方浏览器的的不同,来决定返回哪一个页面;
4)随着时间的推移,到现在的2023年,现代的浏览器都已经差别不大了,UA也已经失去了最初的意义,但是此时的UA又有了一个新的使命,同一个网站,用PC和手机端看到的网页排版是不一样,因为PC和手机的屏幕尺寸是不一样的,PC上的UA和手机上的UA是不一样的,这时就通过获取请求中的UA来判断到底是手机还是电脑,来返回不同版本的样式,这个方法劣势,需要程序员来维护两种版本的代码(也存在过Windows系统的手机);
5)它的一个更主流的方式是用来响应式布局,大概就是获取当前页面的宽度,根据宽度来决定样式,从而实现一份代码,自动修改样式,这就会更加的考验前端工程师的功底了,来适应多种不同宽度的屏幕,屏幕比较宽,就横着排版,屏幕比较窄,就竖着进行排版;
7)手机的浏览器,很多都支持模拟UA,你可以切换UA是其他的值,就可以在手机上看到和PC段类似的网页了;
5)Referer:表示这个页面是从哪里跳转过来的,里面是一个地址;
5.1)这个Referer是不一定有的,像这种直接在浏览器中输入URL,点击收藏夹抓包,抓到的页面请求是没有Referer;
5.2)搜索主页,跳转到搜索结果页,就是带有Referer的,每一个HTTP请求的Referer就是上个跳转的页面;
Referer:类似于搜索广告,怎么挣钱?
1)具体看点击次数,当百度上面的搜索结果有广告的时候,当广告每被点击一次就需要让广告主给搜狗或者百度公司钱,像鲜花,蛋糕,游戏(核心商业词),那么问题来了,我进行投放的某一些广告,具体被点击了多少次,这个是怎么进行计算呢?
2)搜狗肯定是要自己进行计算一份的,搜狗进行计算当前这个页面跳转到哪一个落地页,广告主肯定自己要算一份,计算当前跳转到我这个页面的Referer有多少是搜狗的地址;
3)每次有客户点击就要先跳转到搜狗的服务器,搜狗的服务期看到这个请求就会有专门的服务器来进行统计,叫做bill server,然后再由搜狗跳转到对应的网站落地页,也就是广告界面,这时候的搜狗页面肯定要要计算点击次数,广告主也要自己计算一份,广告主只能拿到自己服务器(网页)的数据,会记录日志,就可以看看自己的服务器上面是有多少请求的Referer是由搜狗服务器那里跳转过来的,然后两边的数据在进行一对,给钱;
4)某一个广告主,在多个平台上面投放了广告,怎么来进行区分?广告主就要按照Referer来进行统计区分当前的请求是哪一个广告平台导入过来的流量,并进行结算,是否可能会有人把这个Referer给改了,从而导致广告主统计错误呢,例如本来有很多的广告是从搜狗那里面跳转过来的,但是实际上有人就解析HTTP数据包,把HTTP请求中的Referer给进行修改了,例如改成XXX公司的,那么此时广告主就会把钱给XXX公司,那么此时搜狗就亏了钱;
5)运营商最有可能做这个事情(像电信,移动,联通等网络运营商),来进行管理网络的一些基础设施比如说路由器交换机,网络流量经过了人家的设备,人家的设备后可以对你的请求进行抓包,并且进行修改操作,况且运营商也有广告平台,况且http协议是进行明文传输的,这个时候完全可以把本属于搜狗的流量就把Referer一改,所以在后续升级成了HTTPS协议;
6)location:搭配3XX状态码来使用,告诉客户端接下来要到哪里去访问;