http在传输层依赖 TCP
客户端与服务器之间的通信模式
- 一问一答:请求与响应一一对应
- 一问多答:
- 多问一答
- 多问多答
抓包工具:Fiddler 相当于代理。 浏览器访问 服务器 时, 就会把 HTTP 请求先发给 Fiddler, Fiddler 再把请求转发给 服务器. 当 服务器返回数据时, Fiddler 拿到返回数据, 再把数据交给浏览器
HTTP 报文格式
请求
首行:方法 URL http版本
header:众多 key:value 每个键值对后面有个换行符
空行:响应报头的结束标记
Body:
响应
首行:http版本 状态码 状态码解释
header:
空行:响应报头的结束标记
Body:
HTTP 请求
URL格式:统一资源定位符
服务器端口号:如果没写就是使用默认的 HTTPS 443 HTTP 80
查询字符串:键值之间使用 = 分隔,键值对之间使用 & 分隔 键值都可以进行转码,是的特殊字符能够被正确传输与解析。只会对特殊字符进行转义例如+ & 空格 汉字 编码规则是 字符对应的码位使用 UTF8(或者其他编码方式) 编码后得到的16进制序列 取后 4 个字节,不足四位直接处理,每个字节对应的16进制表示前面加上 %。例如 中 字的utf816进制序列是 E4B8AD(三个字节)所以对应的URL enclding 是 %E4%B8%AD
片段标识符:用来标记资源中的子资源。#其实就是html中的id,浏览器会直接导航至该资源
HTTP 协议方法
GET 请求
特点:1. body一般为空 2. query String 可以为空也可以不为空 3. header 有若干个键值对
在哪儿可以产生 get 请求:
- 浏览器地址栏输入 url 按回车
- html 中的 a标签 img 标签
- form 表单
- ajax
get 请求的 url 长度有限制吗
http RFC 2616 标准里明确说明了 没有限制 实际 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现. 在浏览器端, 不同的浏览器最大长度是不同的, 但是现代浏览器支持的长度一般都很长; 在服务器端, 一般这个长度是可以配置的.
POST 请求
特点:1. body一般不为空 2. query String 一般为空 3. header 有若干个键值对
POST 和 GET 区别
- 没有本质区别
- 使用习惯有区别
-
-
- get一般用于获取数据 post 一般用于提交数据。因此get一般是幂等的,浏览器会将页面资源缓存,post不是幂等的,一般不会缓存,但是这不是绝对的。例如 购物网站可能会根据用户历史行为,来更新页面内容,所以get每次请求得到的结果就不一样就是不幂等的了。此外,用get请求获取的页面中的广告数据是不会被缓存的。所以说不是绝对的
- get 一般使用 query string 传输数据,post 使用 body (一般遵守的规则)
-
误区:1. get 可以传输二进制数据 post 也可以。2. get 与 post 哪个更安全 取决于 前端是否将数据加密,跟使用 get 还是 post 无关。
http header报头 常见的键值对
- Host: 服务器/接收方 的主机 域名/地址
- Content-Length:body 中数据长度
- Content-Type:请求中 body 的数据格式 常见的有
(1)application/x-www-form-urlencoded
<form action="/submit" method="POST" enctype="application/x-www-form-urlencoded">
<input type="text" name="username" value="zhangsan">
<input type="text" name="password" value="123456">
<input type="submit" value="Submit">
</form>
当用户提交的时候,body 中的数据格式就是这种形式 username=zhangsan&password=123456 键值对之间用 & 分隔,键值之间使用 = 分隔
(2)multipart/form-data form表单提交数据的格式,在form 标签写上 enctype="multipart/form-data" 用于提交图片/文件
(3)application/json 键值对 键必须使用双引号 键值之间使用冒号分隔
注意:因为http是基于TCP的所以为了避免粘包问题,通过设置 Body 长度和 因为有了空行产生了 Body 明确的开头,这就可以很好的避免粘包问题
- User-Agent (UA):表示上网设备信息
- Referer:表示当前页面是从哪个页面跳转过来的,如果从浏览器收藏夹或者通过地址栏则没有 Referer
举个应用例子:投放广告时,广告主可以根据 Referer 来判断 用户是通过哪个网站点击进来的,以此判断流量来源
- cookie & session:用户登录成功后服务器端返回一个令牌(身份标识),以后客户端每次访问服务器的时候就会带上令牌,服务器就知道用户身份是否合法了。服务器端存储的用户信息成为 session
HTTP 响应
状态码
- 200 成功
- 403 访问被拒绝,没权限
- 404 not found 资源没找到
- 405 方法不支持
- 500 服务器内部错误
- 504 超时 当服务器负载比较大的时候容易出现这种情况
- 301 永久重定向
- 302 重定向 例如 用户登录成功后 服务器端发来的响应中的 header 中的 lacation 的值是一个URL,浏览器收到这个响应之后就会 发送 GET 请求
响应 Header
Content-Type
- text/html Body 数据格式是 HTML
- application/json 数据格式是 json
- text/css Body 数据格式是 CSS
- application/javascript Body数据格式是 JavaScript
- application/json Body 数据格式是 JSON
响应正文 Body
- text/html Body 数据格式是 HTML
- application/json 数据格式是 json
- text/css Body 数据格式是 CSS
- application/javascript Body数据格式是 JavaScript
- application/json Body 数据格式是 JSON
通过 form 表单构造 HTTP 请求
form 参数
- action:请求的 URL
- method:是 GET 还是 POST(form 只支持 get 和 post)
- enctype:编码方式 常见的有 application/x-www-form-urlencoded
input 参数
- type:输入框类型 有 text(表示文本),password(表示密码),submit(表示提交按钮)
- name:如果 method 是 get 那么 name 就是 query string 中的 key, value 属性的值就是 默认值
如果 method 是 post enctype 是 application/x-www-form-urlencoded 那么 键值就会在 Body 中键值之间使用 = 分隔,键值对之间使用 & 分隔。 - value 如果 type 是 button 那么 value 就是 按钮上显示的文本。
<form action="/submit" method="POST" enctype="application/x-www-form-urlencoded">
<input type="text" name="username" value="zhangsan">
<input type="password" name="password" value="123456">
<input type="submit" value="提交">
</form>
通过 ajax 构造 HTTP 请求
浏览器给 JS 提供的跟服务器端交互的机制
ajax 默认是异步的,发送方发送后继续往下执行,等结果返回之后浏览器会进行通知,然后就会触发回调函数
浏览器提供的原生API:XMLHttpRequest 使用不方便。很多第三方库对 ajax 进行了封装,我们可以选择 jQuery 库提供的基于对原生 ajax 封装的 API。
引入 Jquery 库流程
- 点击 jQuery CDN
-
点击 minified -
通过 URL 引入 Jquery 或者 下载本地之后引入
Jquery.ajax({
type:"post",
url:"",
data:{},
success:function(result){ //当响应的状态码是200的时候执行此函数
}
});
回调函数:回调函数指的是将此方法作为参数传递给另外一个方法,在执行后者中,满足一定条件再进行执行的函数。上述例子中的 success 还有 Comparator 中的 compare方法 以及 多线程中的 传入Thread 构造函数的 Runnable 中的 run 方法都是回调函数。
跨域问题
上述代码中的 URL 如果是 "http://www.baidu.com", 会把请求发送给百度服务器吗,答案是不会的,因为 最终url 进行拼接的时候会将 http://www.baidu.com 拼接在当前页面的 url 的根路径后面,也就是说形如 http://127.0.0.1:8080/http://www.baidu.com。要想实现跨域,得在服务器端进行设置,本例中则需要在 百度服务器中进行设置
跨域解决方法,在后端中添加 @CrossOrigin
HTTPS
HTTPS + SSL = HTTPS
在 http 基础上将数据进行加密,保证信息安全。
对称加密:使用密钥进行加密和解密。按位异或就是一种简单的 对称加密。因为 一个数按位异或数 A 后,生成密文,然后密文在用 A 异或后就还原了。
非对称加密:引入了 私钥 和 公钥,私钥加密公钥可以解密,公钥加密私钥可以解密。
HTTPS加密机制
通过证书机制生成了一对 私钥1,公钥1。服务器生成了 一对公钥2,私钥2。公钥1是服务器端和客户端事先都知道的,服务器用私钥1对用公钥2生成的Hash1进行加密,将 公钥2 + 加密的hash1 发送给客户端,此时 黑客截取到了 公钥2 + 加密后的 hash1 也没用,因为如果篡改 公钥2,那么用篡改后的公钥2 生成的 hash 跟 hash1 是不一样的。如果篡改 加密的 hash1 和 公钥2,虽然黑客知道公钥1可以将hash1解密,但是黑客没有私钥1,就无法正确加密,所以也就篡改失败。
我们将生成的 hash 称为 数据摘要,加密后的 hash 称为 数字签名