http 和 https 协议

HTTP 协议是互联网的基础协议,作为开发人员,很有必要了解和掌握。学习中参考了大量网络上的资料,比如阮一峰大佬的 HTTP 协议入门等。写下自己的心得与理解。

HTTP 协议

官方定义

HTTP 协议Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

白话文定义

什么是协议?通俗的讲就是约定。而约定是什么?看来得好好学学语文了。

1
2
3
4
5
6
7
# 集市( 菜市场)是指定期聚集进行的商品交易活动形式。--来源于百度百科

买家:您好,您这个东西怎么卖?
商人:5文钱。
买家:看着质量不错,但我钱没带够。这样,您稍等片刻,我回家拿钱,但您不能卖给别人了。
商人:好的,看您诚心要买,我在这等着您,但如果天黑前您没来,我就卖给别人了。
买家:好的。

上面这种常景就是最常见的约定。

套用在HTTP 协议上就可以这么理解:HTTP 协议就是服务器(Server)和客户端(Client)之间进行数据交互(相互传输数据)的一种约定,一种形式。

HTTP 工作原理

HTTP 协议工作于客户端-服务端架构上。
浏览器作为HTTP 客户端通过URLHTTP 服务端WEB 服务器发送所有请求。
Web 服务器根据接收到的请求后,向客户端发送响应信息。
这就是Request/Response(请求/响应)模型
顺带一嘴,C/S架构Client(客户端)/Server(服务器),需要下载客户端才能用的软件就是C/S架构B/S架构Browser(浏览器)/Server(服务器)。各有优缺点,合适的才是最好的。

HTTP 的特点
  • HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type字段标记。
  • HTTP是无连接的。无连接的含义是限制每次连接只处理一个请求。服务器处理完客户端的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。但缺点也很明显,因为需要客户端和服务器三次握手,所以TCP连接的新建成本很高。
  • HTTP是无状态的。HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。但另一方面,在服务器不需要先前信息时它的应答就较快。
  • HTTP是媒体独立的。这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。至于啥是MIME-type:是预定义的Content-Type字段的值和厂商自定义的值的总称。
HTTP 之 URL

HTTP使用URI(Uniform Resource Identifiers)即 统一资源标识符来建立连接和传输数据。URL 是一种特殊类型的 URI,包含了用于查找某个资源的足够信息。
URL 全称是 UniformResourceLocator, 中文叫统一资源定位符,是互联网上用来标识某一处资源的地址。

http://www.baidu.com:80/s?ie=utf-8&wd=百度#1这个URL为例:

  • 协议:这个 URL 的协议部分是 “http:”。后面的 “//“ 是分隔符。
  • 域名:这个 URL 的域名是 “www.baidu.com",通过 DNS 解析后就转换为 IP 地址,当然,也可以直接使用 IP 地址作为域名。
  • 端口:这个 URL 的端口是 “80”,是默认端口,一般默认端口是不显示的,”:80”是我加上去的。至于为啥是 “80”,因为 http 协议默认的端口就是 80,而 https 默认的端口是 443,当然,也可以使用自定义端口。不严谨的说,端口不是 URL 必须的部分,如果省略(也就是不指定)则使用默认端口。
  • 资源目录:这个 URL 的资源目录就是根目录,如果 URL 是http://www.baidu.com:80/search/s?ie=utf-8&wd=百度#1,则资源目录为 search。也就是说,资源目录是从端口后第一个"/"到 最后一个"/"中的内容,不包含"/"。不严谨的说,资源目录不是 URL 必须的部分,如果省略则为根目录。
  • 资源文件:这个 URL 的资源文件为 “s”,事实上是调用搜索模块。资源文件是从最后一个 "/" 到 "?"中的内容,不包含"/"和"?"如果”?”省略(也就是不存在),则是从最后一个 "/" 到 "#"中的内容,不包含"/"和"#",如果 “?”和”#” 都不存在,则是从最后一个 "/" 到 URL 结束的内容,不包含"/"。如果端口后面没有内容,则使用服务器默认的文件。
  • 参数:这个 URL 的参数是从 "?" 到 "#"中的内容,不包含"?"和"#"。参数由key=value 这种格式的键值对组成,可以包含多个参数,多个参数之间用 “&” 分隔。
  • 锚点:这个 URL 的锚点内容是从 "#" 到 URL 结束的内容,不包含"#",锚点都是以 “#” 开始的。锚点内容不是 URL 所必须的。
    HTTP 之 Request
    客户端发送一个HTTP请求到服务器的请求消息包括以下组成部分:
    Request
    由于有道翻译使用了ajax,会局部提交并刷新数据,所以同时出现了 get 请求体post 请求体get 请求体是初始参数,也就是打开网页时的参数,而post 请求体会根据用户输入动态生成,并提交。
  1. 请求方法有很多,常用的就是 get 和 post。简单说,get 用于获取不敏感的数据,post 则用来获取、提交包括用户信息、登录等比较敏感的数据。

  2. 请求 URL 就不用说了。

  3. 请求协议 HTTP 的版本有很多,目前常用的是 HTTP/1.1 ,这个版本:

    • 引入了持久化连接,TCP 可以被复用,对于同一个域名,大多数浏览器允许同时建立6个持久连接。
    • 引入管道机制,在同一个 TCP 连接中,客户端可以同时发送多个请求,这样就进一步改进了 HTTP 协议的效率。
    • 加入了Content-Length 字段,在头部加入 Content-Length 字段,由于一个 TCP 可以同时传送多个响应,就需要有一种机制,区分数据包是属于哪一个回应的,通过 Content-Length 字段声明本次回应的数据长度,而后面的字节就是下一个响应的。
    • 分块传输编码分块传输编码,对于耗时的动态操作,用流模式取代缓存模式,即产生一块数据,就发送一块数据,最后是一个大小为0的块,表示本次回应的数据发送完毕。
    • 客户端请求的头信息新增了Host字段,有了Host字段,就可以将请求发往同一台服务器上的不同网站。
    • 新增请求方法:PUT、PATCH、HEAD、 OPTIONS、DELETE
    • 2015年发布了 HTTP/2 版本,它有几个特性:二进制协议、多工、数据流、头信息压缩、服务器推送。
  4. 请求头。请求头中存储的是这个请求的一些主要说明,也就是常说的自我介绍。服务器根据这些信息来获取客户端的信息。

    • Host:指定服务器域名,用来区分访问一个服务器上的不同服务。
    • Connection:keep-alive 表示要求服务器不要关闭TCP连接,等待其他请求复用,close 表示明确要求关闭连接。默认值是 keep-alive。
    • Content-Length:声明数据的长度,区分数据包是属于哪一个回应的。
    • Accept:客户端向服务器声明自己可以接受哪些数据格式。
    • Origin:指示请求来自于哪个站点。
    • X-Requested-With:如果为 XMLHttpRequest 则为 Ajax 请求,如果为 null,则为同步请求。
    • User-Agent:请求载体的身份标识,使服务器能识别客户端的操作系统(Android、IOS、WEB),浏览器信息及相关的信息。作用是帮助服务器区分客户端,并且针对不同客户端让用户看到不同数据,做不同操作。
    • Content-Type:服务器告诉客户端数据的格式。常见的值有text/plain,text/html,text/css,image/jpeg,image/png,image/svg+xml,audio/mp4,video/mp4,application/json,application/javascript,application/pdf,application/zip,application/atom+xml。这些数据类型总称为MIME TYPE。
    • Referer:告诉服务器,请求是从哪里链接过来。可以用来防盗链、防止恶意请求。如果直接访问,则值为空。
    • Accept-Charset: 告诉服务器。支持的字符集。
    • Accept-Encoding:告诉服务器,可以接受哪些压缩方法。
    • Accept-Language:告诉服务器,支持的语言环境。
  5. 请求体。请求体中存储的是将要传输/发送给服务器的数据信息。

    HTTP 之 Response

    服务器回传一个 HTTP 响应到客户端的响应消息包括以下组成部分:
    Request

  6. 报文协议及版本。和请求协议及版本相同。

  7. 状态码:以“清晰明确”的语言告诉客户端本次请求的处理结果。
    HTTP 的响应状态码由5段组成:

    • 1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急…
    • 2xx 处理成功,一般表示:请求收到、请求已受理、请求已正确处理并完成等信息。
    • 3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
    • 4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
    • 5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。
  8. 响应头。响应信息的详情展示。

    • Location: 告诉浏览器跳到哪个地址。
    • Server:告诉浏览器,服务器的型号。
    • Content-Type:告诉浏览器返回数据的类型。
    • Content-Encoding:告诉浏览器,数据的压缩格式。
    • Transfer-Encoding:告诉浏览器数据是以分块方式回送的。
    • Connection:keep-alive 表示服务器等待其他请求复用,close 表示关闭连接。
    • Content-Length: 告诉浏览器回送数据的长度。
    • Content-Language: 告诉浏览器语言环境。
    • Refresh:告诉浏览器定时刷新。
    • Content-Disposition: 告诉浏览器以下载方式打数据。
    • Expires: 利用浏览器的缓存能力来改善页面的性能,缺点是客户端和服务器时间必须同步。
    • Cache-Control: 用于控制HTTP缓存。
      1. private,代表只有发起请求的浏览器才可以进行缓存。
      2. public,http 请求返回的过程当中,在 cache-control 中设置这个值,代表 http 请求返回的内容所经过的任何路径当中(包括中间一些http代理服务器以及发出请求的客户端浏览器),都可以对返回内容进行缓存操作。
      3. max-age=,缓存多少秒后过期,过期之后浏览器才会再次发送请求。
      4. proxy-revalidate,用在缓存服务器中,指定缓存服务器过期后,必须向源服务器重新请求,不能直接使用本地缓存。
      5. no-store,本地和代理服务器都不可以存储缓存,每次都要重新请求,拿到内容。
      6. no-transform,主要是用在 proxy 服务器,不允许进行格式转换。
  9. 响应体。根据客户端的请求信息,发送给客户端的指定数据。

  10. HTTPS 协议

官方定义

HTTPS (Secure Hypertext Transfer Protocol)安全超文本传输协议HTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是 HTTP协议 的安全版。

白话文定义

加密安全版的HTTP协议。

HTTPS 采用的加密技术
  1. SSL加密技术。SSL采用的加密技术叫做“共享密钥加密”,也叫作“对称密钥加密”。这种加密方法是这样的,比如客户端向服务器发送一条信息,首先客户端会采用已知的算法对信息进行加密,比如MD5或者Base64加密,并在信息发送时传递使用的密钥给服务器(对称加密就是加密和解密使用同一密钥),以便服务器用密钥进行解密。反之服务器也会向客户端发送密钥。这这方法看似安全,但仍有潜在的危险就是,在数据传递过程中一旦被拦截,就有可能使用密钥对信息进行解密。
  2. 非对称秘钥加密技术。“非对称加密”使用的时候有两把锁,一把叫做“私有密钥”,一把是“公有密钥”,使用非对象加密的加密方式的时候,服务器首先告诉客户端按照自己给定的公开密钥进行加密处理,客户端按照公开密钥加密以后,服务器接受到信息再通过自己的私有密钥进行解密,这样做的好处就是解密的密钥根本就不会进行传输,因此也就避免了被挟持的风险。就算公开密钥被窃听者拿到了,它也很难进行解密。但“非对称加密”有两个缺点,一是效率比较低,二是服务器向客户端发送公有密钥时无法保证一定被客户端第一个收到,发送中可能被拦截,并被替换成伪造的公有密钥,从而实现拦截信息并解密。
  3. 证书加密。由于非对称加密的公钥存在被挟持的可能,无法保证客户端收到的公有密钥就是服务器发行的公有密钥。所以就引出了公有密钥证书机制。原理就是,找到客户端与服务器都信赖的第三方数字证书认证机构。然后:
    • 服务器的开发者携带公开密钥,向数字证书认证机构提出公开密钥的申请,数字证书认证机构在认清申请者的身份,审核通过以后,会对开发者申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将密钥放在证书里面,绑定在一起。
    • 服务器将这份数字证书发送给客户端,因为客户端也认可证书机构,客户端可以通过数字证书中的数字签名来验证公钥的真伪,来确保服务器传过来的公开密钥是真实的。一般情况下,证书的数字签名是很难被伪造的,这取决于认证机构的公信力。一旦确认信息无误之后,客户端就会通过公钥对报文进行加密发送,服务器接收到以后用自己的私钥进行解密。