所以说http协议就是浏览器和服务器之间的交互桥梁.
HTTP请求本质上就是给tcp socket里写了一个符合http格式的字符串
我们平时输入的网址,如:baidu.com就是俗称为url
浏览器就是根据这个url构造出一个http请求,发给服务器,服务器就会返回一个http响应(包含了html,css,js,图片),然后再把得到的html等数据显示出来(渲染).
http协议的交互过程,可以借助第三方的工具来看到,这种工具被称为'抓包'工具,抓包工具有很多我们是用的是fiddler.
当你打开这个工具的时候就会立即显示出电脑中某个程序使用http和服务器进行交互的过程
1.可能会和别的代理程序产生冲突,使用的时候要关闭其他的代理程序(包括一些浏览器插件)
正向代理:代表着客户端的代理.
反向代理:代表着服务器的代理.
2.要想要正确抓取包,还要开启https功能.
https是基于http搞出来的进化版协议,当下绝大部分的服务器都是https的fiddler默认不能抓https的包,所以需要我们手动启用一下https并且安装证书.
这些结果就是你在访问浏览器的时候产生的http请求.浏览器打开一个界面对应的浏览器可能是一个也可能是多个.
这个是最重要的https,这个是csdn的主页请求,而其他的就是别的代码的附属请求.
我们可以点击Raw查看这个http请求,http是由一定格式的.fiddler会按照格式解析,然后呈现出不同的显示效果.此处看到的就是最原始的效果.
此处可以看到http请求,其实是个行文本格式的数据,相比于tcp这种二进制格式来说,就更方便用户来直接观察.
这个就是右下角的Raw,响应其实是一个二进制的文件,如果手动复制到记事本,就会发现它是乱码,目的其实是压缩空间,节省带宽.
其实点击上面的一个黄条就可以直接解压缩了:
此时再用记事本查看就能够完整地看他其实这个就是csdn的html代码了!!!
在解码的第一行有一个:
GET https://www.csdn.com/HTTP/1.1
这里的GET是http的方法,和最后的1.1是版本号,中间的是url,俗称就是网址.
这是一个标准的url
它是由rfc标准文档定义的,url不是http专属的.很多协议都可以使用的url比如tcp等
域名/IP
端口号
带层次的路径
查询字符串
举个例子,开饭店,买熏肉大饼:
这是一个常见的https,它省略了端口号,因为浏览器会默认提供端口号,对于http来说默认端口是443
路径其实没有省略,' / '就是路径,代表了根目录,是http服务器的根目录,http服务器是系统上的一个进程,http是系统上的一个进程,就委托这个服务器管理系统上的一个特定的目录,这个目录里的资源都哦可以让外面进行访问.其实就是一个'菜单',而' / '就是就是菜单的根目录,也就是可以使菜单上的任意一个菜.
而查询字符串也是可以省略的,就比如上面的那个例子,如果你什么都不说,那么辣度和香菜和葱就都是默认的正常放!!!
就比如说:
输入这个网址拿到的就和直接baidu.com不一样
注意在这里搜索一个内容然后点进去,此时这个url里就带有query string
这个query是以?开头,以键值对的方式组织.键值对之间使用 &分割,键和值之间使用=分割
如果复制网址的话,
急救室这种情况,它使用了urlencode(转义字符),在url中有些字符都是有特定含义的,所以说就需要对对内容进行重新编码.如果不编码直接访问,可能浏览器就无法正确识别了.
方法描述了这次请求的语义.(也就是你想干嘛)
但是在日常生活中大多数的方法都是见不到的,get能占据你见到的方法的80%.
但是其实,这个方法的语义只是方法设计者的初心,跟实际的功能几乎没有关系,也就是说你想怎么用就这怎么用.
get请求的触发情况:
在浏览器的地址栏中直接输入url
html里的link,script,img,a.
通过js触发get请求.
这是一个"百度一下"网页的抓包,我们看这个就是使用了get请求.
这是一个网页的登录界面,当点击登录的一瞬间,会发生网页的跳转现象,此时就会触发post方法.
HTTP的请求可以划分为四个部分:
首行,抓包内容的第一行被称为首行(告知了使用方法以达到什么的作用).
header
空行
正文(body)
如果是get请求一般没有body,如果是post请求,一般有body
而这一部分就是post请求里的body:
另外,这一部分的内容是程序员自己定义的,想传啥就传啥.这里面的uuid是一个身份标识,但是具体的规定方式,只有设定它的程序员可以看懂.
1.相比来说其实get也可以进行消息的传送,get传递的消息一般都是放在query string.POST传递消息则是通过body.这也是他们俩之间最本质的区别.
2.语义上的差别
get请求一般都是用于从服务器获取数据,post请求一般是用于给服务器提交数据
3.get通常会被设计成幂等的,但是post不要求幂等.
解释一下幂等:就是你输入的值相同,得出来的结果也一定是相同的.
这个区别只是一个习惯性的用法,都是可以程序员设定的,怎么来都行,只是别人看不懂.
4.由于get是幂等的所以可以被缓存,而post则一般不能被缓存.(把请求的内容保存下来,如果下次再请求相同的内容,则可以不必进行再次请求直接返回相同的内容,前提得是幂等的)
使用:进行键值对的分割.
这些键值对都是http实现定义好的,都是有特殊含义的.
1.Host
host就是描述了服务器的地址和端口.
在url不是存放了地址和端口吗?为什么要多存一份?
大多数时候host和url里的地址和端口都是相同的,但有时是不同的.
2.
就是在header 的这里:
如果是get请求,没有body,请求中就没有这俩字段.
如果是post请求,有body,则必须要这两个字段.
如上面所言,这个就是用来盛放body中的长度和数据格式的.
3.
抓包内容是:
看到其中有windows、chrome......
其实这个键值对就是表述了当前用户的操作系统和浏览器的版本
现在操作系统和浏览器已经趋于统一的时代,几乎已经没用了.
但是放在以前的年代就非常有用了!!!
现在的user-agent都是用来区分手机端/PC端
4.referer
这个就是描述页面的"来源".
直接输入地址或者是从收藏夹点击进来时,都是没有referer,只有通过网页点击进来的网页才是拥有referer的.
讲一个生活中的例子:广告
一个浏览器上的广告,是怎么向广告版权方收取费用的呢?
按点击收费,就是浏览器的公司统计一个referer,然后广告版权方再统计一个referer,最后看一看对得上不,对得上就按这个点击量收费,对不上再进行二次统计.
5.
这也是一个重要的header属性.
本质上是一个 浏览器 给网页提供的 本地存储数据 的机制.
这里有一个前提:网页是默认不允许访问你的硬盘的.(保证安全)
但是我们也还是需要让浏览器在本地存储一些信息:比如说现在有的那个记忆密码功能.
所以说cookie浏览器对于访问硬盘就对访问硬盘做出了明确的限制.
cookie就是通过键值对的方式来组织数据的.
另外,这个cookie 的存储都是程序员自定义的内容.
这个大量的键值对,键和值之间通过' = '来进行连接,键值对和键值对之间通过' ; '进行分割.
具体数据的含义,只有开发人员才知道.
另外,也可以直接点击左上角:
这个cookie直接查看里面存放的键值对.
这是我们浏览器设计人员给本地存储设置的一个口子,是和硬盘分离的,既可以存储信息,又可以保证我们极端及的安全.
cookie在存储的时候,是按照 浏览器+域名的方式进行存储的,所以说不同的浏览器乃至不同的域名都会各自存储各自的cookie.
除了键值对,cookie中还存储着过期时间(过期后会自动删除cookie).
另外,cookie还会存储用户使用的中间状态.当客户端访问浏览器时,就会自动的把cookie带入到当前的请求中(类似之前的上下文的状态),此时服务器就可以知道客户端是怎样个状态.
举个例子:比如你玩一款游戏,然后现在有急事不能玩了,然后退出了游戏,此时游戏就会自动存档,cookie就相当于游戏自动存档的那个组件,然后等你办完事了,回来继续玩,此时的你可能已经忘记了玩到哪了,但是cookie会帮助你主动回忆你的游戏进程.
依然还是抓一个响应的包:
首行
版本号 状态码 状态码描述
2.header
依然还是上面那几个键值对
3.空行 表示header的结束标志
4.body
描述了这次响应的结果是成功了,还是失败了.原因是啥
百度一下:
这里主要说几个常见的状态码:
1.200 OK 成功了
2.404 Not Dound 访问的资源不存在,在服务器上没找到.
3.403 Forbidden 访问被拒绝(没有权限)
4.302
重定向(就类似于呼叫转移)
另外,3XX的都是类似的效果,都是重定向.
5.500 服务器内部错误(服务器代码抛异常)
6.504 gateway timeout(响应时间太长,浏览器等不及了)
1XX也就是等一等,请求还没有完成
2XX一般表示成功
3XX重定向,就是此路不通,找别的路
4XX也就是客户端这边出问题了
5XX也就是说服务器这边出现了问题
url的路径
url中的query string
header中的键值对
header中的cookie的键值对
body
都是上面说过的
爬虫这方面不能过多展开,只是说说原理:
举个例子:比如你要写一个自动化点赞的代码.
此时你只需要利用抓包工具将点赞这个事件的包抓住打开,然后开开点赞这个事件是以怎样个形式组成字符串的,然后通过代码的形式直接给服务器发送这个字符串,此时服务器是分不清到底是客户端发送的还是你自己的代码发送的包.就会一并解析,此时就达到了自动化点赞的目的.
但是,一定要注意:一但你写的程序由bug,就相当于是你写了程序自动攻击人家的服务器,如果造成人家的服务器瘫痪,产生财产损失,是要判刑的!!!但是一般的服务器都是有反爬功能的.
但是一般学校的官网都是没有反爬的
地址栏直接输入
点击收藏夹
html中的link script img a
from标签
from 标签可以实现用户和服务器之间的交互,
其中有两个比较重要的属性:
一个是action属性可以明确这次请求需要提交给那个服务器
另外一个是method属性,这个属性可以明确在信息交互的过程中使用的是什么方法
这里我们构造了一个按钮,通过点击这个按钮既可以实现表单的"提交操作",也就是构造一个http请求发给服务器.
点击提交自动跳转action 的网页,此时利用fiddler进行抓包:
这是数据提交的内容:
其中第一行的内容分别是方法、action、用户输入的值(studentName)、版本号.
之后的键值对存储的数据都是浏览器自行进行设置的.
此时的方法依然变为了post,我们发现相比get包,put包将用户输入内容从query string部分移动至了body 部分,键值对之间使用&来进行分割,键和值之间使用:进行分割.
注意:from标签只能构造post 和get ,无法构造put,delete,options等方法
除了我们现在额这种构造http请求的方式,还有一个更加好用的,功能那个更加齐全的方式:ajax(啊加克斯)
这里的a指的是异步的概念.
这里解释一个异步这个名词:
异步和同步.A等待B,同步是指A始终盯着B,A负责关注B啥时候就位.
异步是指A不盯着B,B就绪后主动通知A.
这里常见的形式就是异步的方式进行同步.
而在html中,通过ajax发起http请求,就属于是"异步"的方式.
这一行代码执行"发送请求"操作之后,不必等待服务器响应回来,就可以立即先向下执行,当服务器的响应回来之后,再由浏览器通知到我们的代码中 .
js原生提供的ajax的api,但是原生的很难用.
jquery提供的ajax,api针对原生的api的封装,简单很多.
首先是一个
注意:这里的$这的全局对象,我们在之后用的所有的api都是由$引出的.
之后就是我们的使用方法了:
在这个ajax中添加了get方法,url,用户输入内容等信息.
最后设置了一个回调函数,而这个success会在服务器响应浏览器请求的时候进行发生回调.
这个success正是"异步"的体现.
注意:该代码直接进行执行,只是能看到构造的请求无法获取到正确的响应.因为搜狗的服务器没有办法处理我们所写代码的请求.
响应结果:
此时程序是无法执行的,因为搜狗服务器无法处理我们的请求,当我们能够编写正确的服务器程序后就可以实现了!!!
和from相比,ajax 的功能更强:
支持put,delete的方法
ajax发送的请求可以灵活设置header
ajax发送的请求的body也是可以灵活设置的
另外,出了这两种构造http的方式,如果在测试的环境下,在我们不能够进行代码编写http和环境下,就可以使用到postman这种工具进行http的编写.
先注册
创建workspace
新建一个标签页
就可以随心所欲的创建http请求了
这里的url,方法,设置键值对都是可以随心所欲的设置的.
另外,body和header方面也是可以直接进行操控的:
点击send:
此时我们的请求的响应就此回来了.
通过上述的操作我们就可以配置一个http请求.
它可以生成构造http请求的不同语言代码,方便我们进行代码的集成
点击这个code图标.
就可以进行当前http请求不同语言的代码!!!
https其实就是http+安全层(SSL)
安全层就是用来加密的协议SSL/TLS
网络上如果数据明文传输数据,是非常危险的,就需要加密来保证安全.
比如在网络上,经常会发生下载东西的时候,明明点的是要安装百度浏览器,但是却安装了360浏览器的这种情况,这种情况被称为"运营商劫持"事件.也就是运营商将百度浏览器的链接给替换成了360浏览器的链接,进而获取利益的行为.而这就是数据明文传输的缺陷.所以说此时https就被发明出来了,也就是加密版本的http协议.
加密其实就是将想要传达的信息(能够直接看懂的信息),通过某种格式进行复杂化,成为无法直接读懂的信息.然后让接收方获取一个"密钥",只有配合"密钥"才能够将信息读懂.其中,就算信息被截获,截取方也是看不懂的.
接下来,所讲述的过程说是HTTPS的,但其实就是SSL加密部分的工作,SSL不只是应用在HTTPS,在大多数的信息传输类工程中都有用到.
进行安全传输,核心就是加密
a(明文) + key=>b(密文) 加密的过程
b(密文)+ key=>a(明文) 解密的过程
同一个密钥,可以用来加密,也可以用来解密,这种密钥就被称为"对称密钥".
对称加密安全性的前提就是密钥不能被别人知道.
我们要明确一个前提,密钥都是客户端生成的!!!
因为一个服务器要同时响应对个客户端,如果密钥由服务器生成,就相当于每个客户端的密钥都是一致的,这样更加方便黑客进行获取!!!
这时我们假设,在传输密文之前要进行密钥的传输,但是如果黑客在传输密钥之时就已经入侵了服务器呢?
那么咱们的加密就相当于形同虚设了.
所以此时我们对我们首先进行传输的密钥也要进行加密.
但是此处我们引入的加密方式是:非对称加密!!!
生成一对密钥:
公钥
私钥
明文+公钥=>密文 使用公钥进行加密
密文+私钥=>明文 使用私钥进行解密
或者反过来也可以.
服务器生成一堆密钥:公钥 私钥
客户端持有公钥
服务器持有私钥
此时客户端从服务器获取公钥,黑客可能知道公钥.
但是黑客不知道私钥,私钥是服务器自己才有的.
客户端使用公钥,来对对称密钥进行加密,传给服务器,服务器就可以拿着自己的私钥来解密得到对称密钥.
这是信息就能够保证安全了!!!
但是有一个问题,此时有了非对称加密,那为什么还要保留非对称加密呢?直接使用非对称加密加密所有不好吗?
不可以,因为非对称加密要慢,而对称加密快.考虑速度的情况,使用这一种对称加密和非对称加密的方式是最合理的!!!
中间人攻击就是指,黑客充当中间人的身份,扮演双方,让双方都认为自己是 服务器/客户端.然后进一步的获取用户信息.
如上图,接下来讲述一下中间人攻击的具体流程:
首先是服务器按照非对称密钥的形式生成一堆公钥/密钥(pub1/pri1),然后客户端想要进行信息的交互,向服务器询问公钥是啥?但是这条信息没有直接到达服务器,而是被黑客截获.此时再转由黑客的手向服务器提出公钥申请.
接下来,服务器向黑客返回公钥pub1,此时黑客自己生成一组公钥/私钥(pub2/pri2),然后将自己生成的pub2发送给客户端充当"公钥".黑客此时自己存下pub1.
此时客户端收到公钥pub2,并且生成对称密钥key,使用公钥对key进行加密.客户端此时无法判断pub2是不是真实的公钥,所以将这个公钥当做正确的公钥来用,给了黑客可乘之机.
接下来,客户端发送对称密钥(使用pub2加密后的),此时黑客就拿到了对称密钥,并且使用自己的pri2进行解密,从而拿到了客户端生成的对称密钥key.
接下来黑客将对称密钥key 使用pub1进行加密发送给服务器,此时服务器使用私钥pri1进行解密得到了对称密钥key(可是此时黑客也一样得到了).之后服务器和客户端交互的信息,虽然都已经加密过了,但是因为黑客依然拿到了对称密钥key,是的加密荡然无存了!!!
在以上过程中,黑客是在客户端和服务器都无法察觉的情况下进行的.毫无反制手段.
解决中间攻击的关键,在于让客户端能够判别当前这个公钥是不是服务器真是的公钥.
所以在此处引入一个"证书"(本质上是引入第三方的公证机构)相当于找了一个人/机构做的担保
服务器(网站)在设立之初,就需要去专门的认证机构,申请证书 (提供一些相关文件)
审核通过,就会给你办法证书
服务器生成的公钥,也就包含在了这个证书中了!!!
客户端向服务器请求公钥的时候,就不是单单请求一个公钥,而是把整个证书都给请求过来了.
客户端拿到证书之后就可以对证书进行校验.(检验证书是不是假的)如果发现证书是假的,浏览器就会直接弹框警告 (某些小网站就会有这种情况)
证书
字段1:aabc
字段2:ccde
字段3:ddef
公钥:0xaabbccddee......
签名:hsoahfnklsjxghbihjlkjnlkj(相当于一串加密的字符串)
计算机会对签名进行解密,解密之后会得到一个hash1值(这个hash值是一个校验和)
然后客户端会更具证书里面的算法,对字段1......n和公钥进行计算,能得到一个hash2(自己算的校验和)
之后检验一个hash1和hash2是否一致.如果一样就说明证书是真的;如果不一样证书就是假的.
一但黑客替换的公钥,就意味着hash1和hash2不一致了,证书就是假的了!!!
另外,黑客因为不知道认证公司的私钥,即使黑客自己算好了hash值也无法自动生成签名.