为何要有应用层?
我们知道数据能从客户端经过路径选择跨网络从而送到服务器端进程(ip+port),可是,仅仅把数据从A点送到B点就结束了吗?这就好比,在淘宝上买了一部手机,卖家(客户端)把手机通过顺丰(传送+路径选择)送到卖家(服务器)手里就结束了吗?
当然不是,买家还要实用这狂产品,还要在使用之后,给卖家打分评论。所以,我们把数据从A端传送到B端,TCP/IP解决的是顺丰功能,而两端还要对数据进行加工处理或者使用,所以我们还需要一层协议,不关心通信细节,关心应用细节!
这层协议叫做应用层协议。而应用是有不同场景的,所以应用层协议是有不同种类放入,其中经典的协议之一就是HTTP。
如何理解应用层协议呢?
再回到我们刚刚说的买手机的例子,顺丰相当于 TCP/IP 的功能,那么买回来的手机都附带了
说明书【产品介绍,使用介绍,注意事项等】,而该说明书指导用户该如何使用手机【虽然我们
都不看,但是父母辈有部分是有看说明书的习惯的:)】,此时的说明书可以理解为用户层协议
HTTP协议
HTTP协议是超文本传输协议(请求-响应协议),,通常运行在TCP之上(80端口),它指定了客户端发送什么样的消息给服务器以及得到什么样的响应。
HTTP协议是一种无状态协议,服务器不保留和用户交易时的任何状态,这就大大减轻了服务器的记忆状态;从而有较快的响应速度。
认识URL
平时我们俗称的“网址”其实就是说的URL
1、协议方案名:HTTP、HTTPS
2、登录信息(认证):指定用户和密码作为从服务器端获取资源时必要的登录信息(身份认证)。
可选项。
3、服务器地址:待访问的服务器地址
4、服务器端口号:指定服务器连接的网络端口号
5、带层次的文件路径:指定服务器上的文件路径来定位特定资源。
6、查询字符串:针对已指定的文件路径内的资源,可以查询字符串传入任意参数。可选项。
7、片段标识符:使用片段标识符通常科技标记出已获取资源中的子资源(文档内的某个位置)。
可选项。
HTTP协议格式
HTTP常见的Header(报头)
Host:客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
Content-Type: 数据类型(text/html等)
Content-Length:Body的长度
User-Agent:声明用户的操作系统和浏览器版本信息
referer: 当前页面是从哪个页面跳转过来的;
location:搭配3xx状态码使用, 告诉客户端接下来要去哪里访问
Cookie:用于在客户端存储少量信息,通常用于实现会话(session)功能
常见的Content-Type
Content-Type: text/html
Content-Type: text/plain
Content-Type: application/javascript
Content-Type: application/json
Content-Type: image/jpeg
HTTP的方法
方法 | 说明 |
---|---|
GET | 获取资源(1.0、1.1) |
POST | 用于添加新的资源,用于表单提交(1.0、1.1) |
PUT | 用于修改某个内容(1.0、1.1) |
HEAD | 获取报文首部 (1.0、1.1) |
DELETE | 删除某个内容(1.0、1.1) |
OPTIONS | 询问支持的方法(1.1) |
CONNECT | 要求隧道协议连接代理(1.1) |
LINK | 建立和资源之间的联系(1.0) |
UNLINE | 断开连接关系(1.0) |
TRACE | 追踪路径 (1.1) |
HTTP状态码
表中标黄的为常见的HTTP状态码
100 Continue | 继续。客户端应继续其请求 |
---|---|
101 Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级别的协议,例如,切换到HTTP的新版本协议 |
200 OK | 成功响应 |
301 Moved Permanently | 请求对象已被永久性转移, 新的URL定义在响应报文的首部行,客户端将自动获取 |
302 Found | 与301类似,但资源只是临时被移动, 客户端继续使用原有的URL |
303 See Other | 查看其他地址。与301类似,使用GET和POST请求查看 |
304 Not Modified | 未修改。锁请求的资源为修改,服务器返回状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通常提供一个头信息指出客户端希望之返回在指定日期之后修改的资源 |
305 Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
306 Unused | 已经被废弃的HTTP状态码 |
307 Temporary Redirect | 临时重定向。 与302 类似,使用GET请求重定向 |
400 Bad Request | 通用的差错代码,请求不能被服务器理解 |
401 Unauthorized | 未认证,缺乏相关权限 |
402 Paryment Required | 保留将来使用 |
403 Forbidden | 服务器理解客户端的请求,但是拒绝执行 |
404 Not Found | 被请求的文档不在服务器上,有可能因为请求URL出错 |
405 Method Not Allowed | 客户端中请求的方法被禁止,例如限制POST方法但使用了GET访问 |
500 Internal Server Error | 服务器内部错误,无法完成请求 |
501 Not Implemented | 服务器不支持请求的功能,无法完成请求 |
502 Bad Gateway | 作为网关或代理工作的服务器尝试执行请求时,从源端服务器收到了一个无效响应 |
503 ServiceUnavailable | 由于超载或系统维护,服务器暂时无法处理客户端事务请求 |
504 Gateway Timeout | 充当网关或代理的服务器,为及时从远端服务器获取请求 |
505 HTTP Version Not Supported | 服务器不支持请求报文使用的HTTP版本 |
小结:
HTTP状态共有五种类型
分类 | 分类描述 |
---|---|
1xx | 信息,服务器收到请求,需要请求者继续执行操作 |
2xx | 成功,操作成功接收并处理 |
3xx | 重定向,需要进一步的操作以完成请求 |
4xx | 客户端错误,请求包含语法错误或无法完成请求 |
5xx | 服务器错误,服务器在处理请求的过程中发生了错误 |
cookie和session
http是一个无状态协议, 就是说这一次请求和上一次请求是没有任何关系的,互不认识的,没有关联的,每次用户的请求到达服务器时,HTTP服务器并不知道这个用户时谁,是否登录过等。这种无状态的的好处是快速。坏处是需要进行用户状态保持的场景时,(比如,登陆状态下进行页面跳转,或者用户信息多页面共享等场景,)必须使用一些方式或者手段比如: session 和 cookie。cookie和session就是为了维持会话状态。
cookie
如上所述,http是一个无状态的协议,但访问有些资源的时候往往需要经过认证的账户才能访问,而且要一直保持在线状态,所以,cookie是一种在浏览器端解决的方案,将登录认证之后的用户信息保存在本地浏览器中,后面每次发起http请求,都自动带上该信息,就能达到认证用户,保持用户在线的作用。
什么是cookie?
Cookie是保存在客户端的纯文本文件,比如txt文件。当我们的使用电脑进行浏览器访问网页时,服务器就会生成一个证书并返回给我们浏览器并写入我们本地电脑。这个证书就是Cookie。
当你浏览网页时Cookie这个文本文件可以记录你的用户ID、密码、浏览过的页面、停留的时间等信息。当再次访问该网站时,网站就可以通过读取Cookie得知你的相关信息并作出相应动作。例如不需要输入ID、密码等就可以直接登录。如果清理了cookie则登陆过的网站就没有相关信息。
cookie实现机制
1、浏览器(或者客户端)向某个URL发送HTTP请求
2、对应的HTTP服务器收到该HTTP请求,并计算应当返回給浏览器的HTTP响应。
3、返回的响应中含有Set-Cookie字段,它的值为要设置的cookie
4、浏览器(客户端)收到来自服务器的HTTP响应,在响应头中发现Set-Cookie字段,然后
将该字段保存在内存或者硬盘中。
5、浏览器下次給该服务器发送HTTP请求的时候,就会简化服务器设置的cookie加在HTTP请求头
的Cookie字段中。浏览器可以存储多个域名下的Cookie,但只发送当前请求的域名曾指定Cookie,
这个域名也可以在Set-Cookie字段中指定。
6、服务器收到这个HTTP请求,发现请求中有Cookie字段,便知道之前就和这个用户打过交道了。
这样就辨别了浏览器。
7、返回响应。过期的Cookie会被浏览器(客户端)删除。
服务器通过Set-Cookie响应头字段种下Cookie,指示浏览器保存Cookie;浏览器通过Cookie请求投字段来告诉服务器之前的状态。Cookie中包含若干个键值对,每个键值对都可以设置过期时间。
Cookie的问题(缺点)
有了Cookie提供了方便,可以实现免密登陆等
但同时也有很大的缺点:
(1)Cookie保存在本地文件中,是不安全的,用户可以进行修改。
通常跨站点脚本攻击利用网站的漏洞在网站页面植入脚本代码,脚本指令将会读取当前站点的所有Cookie内容。
(2)浏览器可以禁用cookie,但禁用后也无法享受cookie带来的方便。
(3)数量受限制,一个浏览器能创建的cookie数量最多为300个,并且不能超过4KB,每个web站点能设置的cookie宗主不能超过20个。
解决方法:
将发送给用户的Cookie进行加密,服务器取到Cookie后先解密
服务器可以为每个Cookie项生成签名,由于用户篡改Cookie后无法生成对应的签名, 服务器便可以得知用户对Cookie进行了篡改。
1、在服务器中配置一个字符串(secret),例如:x$sfz32
2、当服务器需要设置Cookie时(比如authed=false),不仅设置authed的值为false, 在值的后面进一步设置一个签名,最终设置的Cookie是authed=false|6hTiBl7lVpd1P。
3、签名6hTiBl7lVpd1P是这样生成的:Hash('x$sfz32'+'false')。 要设置的值与Secret相加再取哈希。
4、用户收到HTTP响应并发现头字段Set-Cookie: authed=false|6hTiBl7lVpd1P。
5、用户在发送HTTP请求时,篡改了authed值,设置头字段Cookie: authed=true|???。 因为用户不知道Secret,无法生成签名,只能随便填一个。
6、服务器收到HTTP请求,发现Cookie: authed=true|???。服务器开始进行校验: Hash('true'+'x$sfz32'),便会发现用户提供的签名不正确。
通过给Cookie添加签名,使得服务器得意知道Cookie被修改,但这样还是不安全的。因为Cookie是明文传输的,只要服务器设置过一次authed=true|xxxx用户就会知道true的签名是什么了,以后就可以用这个签名来欺骗服务器了。
所以不要将敏感信息放入Cookie中。
cookie有有效期:
1、会话级别有效期:浏览器关闭就没了cookie
2、Set-Cookie可以设置过期时间,在过期时间内一直有效,关掉浏览器再打开也有。
cookie是否可以跨域?
不可以;
一个cookie只能用于一个域名,不能发给其他域名。
什么是跨域?
当一个请求url的协议、域名、端口号三者之间任意一个与当前页面的url不同即为跨域。
session
cookie+session实现机制
将用户敏感信息保存至服务器,而服务器本身采用md5算法或相关算法生成唯一值(session id),将session id保存在客户端浏览器中,之后,客户端再次发送请求就会携带该session id,进而在服务端认证,达到状态保持的效果
cookie vs session
cookie和session的区别
1、cookie只能存储ASCII码,而session可以存储任何类型的数据
2、session存储在服务器,而cookie以文本格式存储在客户浏览器中,容易被恶意查看。
3、session的运行依赖session_id,而sessionid存在cookie中,叫做JSESSIONID。如果浏览器禁用了cookie,同时session也会失效(可以通过其他方式实现,比如在url中传递session_id)
4、因为每次发起http请求,都要携带有效cookie信息,所以cookie一般有大小限制,以防止增加网络压力,一般不超过4k。
浏览器 ----> 开发者工具 ---->Application 进行查看cookies