继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

http深入浅出

resharpe
关注TA
已关注
手记 102
粉丝 7244
获赞 3476
1. 写作目的及题材范围介绍

HTTP 协议是互联网的基础协议,也是网页开发(无论前后端)的必备知识。若想在专业技术道路上走得更坚实,绝对不可能绕开学习HTTP协议这一环节。对基础及核心部分的深入学习是成为一名优秀技术人员的前提。

2. http/https背景及发展简介,基本概念简介

HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。

  • 网络基础TCP/IP: 网络分层
  • HTTP超文本传输协议(Hypertext Transfer Protocol):

用于传输超媒体文档(如HTML)的应用层协议。 它专为Web浏览器和Web服务器之间的通信而设计,但也可用于其他目的。 HTTP遵循传统的客户端-服务器模型,客户端打开连接以发出请求,然后等待它收到响应。 HTTP是无状态协议,这意味着服务器不会在两个请求之间保留任何数据(状态)。 虽然通常基于TCP / IP层,但它可以在任何可靠的传输层上使用; 也就是说,一种不会无声地丢失消息的协议,例如UDP。

  • HTTP是一种允许获取资源的协议,例如HTML文档。 它是Web上任何数据交换和客户端- 服务器协议的基础,这意味着请求由接收者(通常是Web浏览器)发起。 从所获取的不同子文档重建完整文档,例如文本,布局描述,图像,视频,脚本等。

  • URI/URL/URN:
    • URI(Uniform Resource Indentifier):由某个协议方案表示等资源定位标识符。包含UIL(Location)和URN(永久资源定位符)
  • 报文格式:

三次握手

确保数据到达目标:三次?(three-way handshaking)
TCP的flag:SYN(synchronize)和ACK(acknowledgement)

  • syn
  • syn + ack
  • ack

http发展

  • http/0.9
    • 只有一个命令get
    • 协议规定,服务器只能回应HTML格式的字符串,不能回应别的格式。
    • 没有header等描述数据的信息
    • 服务器发送完毕,tcp连接就关闭
  • http/1.0

    • 任何格式的内容都可以发送。这使得互联网不仅可以传输文字,还能传输图像、视频、二进制文件
    • 更多命令(GET命令,还引入了POST命令和HEAD)
    • HTTP请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(HTTP header),用来描述一些元数据。
    • 其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。
    • HTTP/1.0 版的主要缺点是,每个TCP连接只能发送一个请求。
    • Content-Type 字段:关于字符的编码,1.0版规定,头信息必须是 ASCII 码,后面的数据可以是任何格式。因此,服务器回应的时候,必须告诉客户端,数据是什么格式
  • http/1.1
    • 持久连接(persistent connection):TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive
    • pipeline:在同一个TCP连接里面,客户端可以同时发送多个请
    • Content-Length 字段:一个TCP连接现在可以传送多个回应,势必就要有一种机制,区分数据包是属于哪一个回应,声明本次回应的数据长度.
    • 分块传输编码:产生一块数据,就发送一块,采用"流模式"(stream)取代"缓存模式"(buffer)
    • 增加host和其它命令(PUT、PATCH、HEAD、 OPTIONS、DELETE),客户端请求的头信息新增了Host字段,用来指定服务器的域名.Host: mp.weixin.qq.com
    • 缺点:队头堵塞,为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。
  • SPDY 协议:2009年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。这个协议在Chrome浏览器上证明可行以后,就被当作 HTTP/2 的基础

  • http2(2015年,HTTP/2 发布。它不叫HTTP/2.0,是因为标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3。)
    • 只有在 HTTPS 环境才会生效
    • 二进制协议:头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。可以定义额外的帧
    • 多工(Multiplexing):同一个连接里发送多个请求无需按顺序
    • 数据流:每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,可以被其他请求使用。客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。
    • 头信息压缩(header compression):
      推送更高效,一方面,头信息使用gzip或compress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
    • 服务器推送(server push):HTTP/2 允许服务器未经请求,主动向客户端发送资源。服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。
3. http常见特性总结及梳理 4. 常见跨域情形,几种常见跨域解决方案及原理

浏览器同源政策及其规避方法

  • 同源策略(Same-origin_policy)
  • 同源:协议&&域名&&端口三者均相同;
  • 同源目的:保证用户信息的安全,防止恶意的网站窃取数据;
  • 同源限制:
    • Cookie、LocalStorage 和 IndexDB 无法读取;
    • DOM 无法获得;
    • AJAX 请求不能发送
  • Ajax:同源政策规定,AJAX请求只能发给同源的网址.除了架设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),有三种方法规避这个限制:

    • jsonp:简单,老式浏览器全部支持,服务器改造非常小.不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。但只支持GET请求。
    • websocket:WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。有一个字段是Origin,表示该请求的请求源(origin),即发自哪个域名.
    • CORS:

      • CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
      • 请求分类:
        • 简单请求(simple request):
          1. 请求方法是以下三种方法之一:HEAD/GET/POST
          2. HTTP的头信息不超出以下几种字段:
            Accept/Accept-Language/Content-Language/Last-Event-ID/Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
        • 非简单请求(not-so-simple request):非上
      • 请求分类处理:

        • 简单请求:

          • 头信息之中,增加一个Origin字段:说明,本次请求来自哪个源(协议 + 域名 +端口)。服务器根据这个值,决定是否同意这次请求。
          • 如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。

            • Access-Control-Allow-Origin:必须,接受请求的域名
            • Access-Control-Allow-Credentials:可选,是否允许发送Cookie。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。Access-Control-Allow-Credentials: true;另一方面,开发者必须在AJAX请求中打开withCredentials属性。var xhr = new XMLHttpRequest();xhr.withCredentials = true; :如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie

            • Access-Control-Expose-Headers:可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定
        • 非简单请求:对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
          • 预检请求:非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
            OPTIONS /cors HTTP/1.1
            Origin: http://api.bob.com
            Access-Control-Request-Method: PUT //CORS请求会用到哪些HTTP方法
            Access-Control-Request-Headers: X-Custom-Header
            Host: api.alice.com // 浏览器CORS请求会额外发送的头信息字段
            Accept-Language: en-US
            Connection: keep-alive
            User-Agent: Mozilla/5.0...
          • 预检响应:
            HTTP/1.1 200 OK
            Date: Mon, 01 Dec 2008 01:15:39 GMT
            Server: Apache/2.0.61 (Unix)
            Access-Control-Allow-Origin: http://api.bob.com  //同意跨源的url
            Access-Control-Allow-Methods: GET, POST, PUT //服务器支持的所有跨域请求的方法
            Access-Control-Allow-Headers: X-Custom-Header //服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段  
            Access-Control-Max-Age :3600 //本次预检请求的有效期,单位为秒。
            Content-Type: text/html; charset=utf-8
            Content-Encoding: gzip
            Content-Length: 0
            Keep-Alive: timeout=2, max=100
            Connection: Keep-Alive
            Content-Type: text/plain

跨域通用解决方案

5. RESTful 简介

REST(REpresentational State Transfer)这个概念,首次出现是在 2000年Roy Thomas Fielding(他是HTTP规范的主要编写者之一)的博士论文中,它指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful的。

简单地理解就是@Ivony
老师
URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。

要理解什么是REST,我们需要理解下面几个概念:

  • 资源(Resources)
    REST是"表现层状态转化",其实它省略了主语。"表现层"其实指的是"资源"的"表现层"。

    那么什么是资源呢?就是我们平常上网访问的一张图片、一个文档、一个视频等。这些资源我们通过URI来定位,也就是一个URI表示一个资源。

  • 表现层(Representation)

    资源是做一个具体的实体信息,他可以有多种的展现方式。而把实体展现出来就是表现层,例如一个txt文本信息,他可以输出成html、json、xml等格式,一个图片他可以jpg、png等方式展现,这个就是表现层的意思。

    URI确定一个资源,但是如何确定它的具体表现形式呢?应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对"表现层"的描述。

  • 状态转化(State Transfer)

    访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,肯定涉及到数据和状态的变化。而HTTP协议是无状态的,那么这些状态肯定保存在服务器端,所以如果客户端想要通知服务器端改变数据和状态的变化,肯定要通过某种方式来通知它。

    客户端能通知服务器端的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

综合上面的解释,我们总结一下什么是RESTful架构:

  • (1)每一个URI代表一种资源;
  • (2)客户端和服务器之间,传递这种资源的某种表现层;
  • (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

Web应用要满足REST最重要的原则是:客户端和服务器之间的交互在请求之间是无状态的,即从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外此请求可以由任何可用服务器回答,这十分适合云计算之类的环境。因为是无状态的,所以客户端可以缓存数据以改进性能。

另一个重要的REST原则是系统分层,这表示组件无法了解除了与它直接交互的层次以外的组件。通过将系统知识限制在单个层,可以限制整个系统的复杂性,从而促进了底层的独立性。

下图即是REST的架构图:

图8.5 REST架构图

当REST架构的约束条件作为一个整体应用时,将生成一个可以扩展到大量客户端的应用程序。它还降低了客户端和服务器之间的交互延迟。统一界面简化了整个系统架构,改进了子系统之间交互的可见性。REST简化了客户端和服务器的实现,而且对于使用REST开发的应用程序更加容易扩展。

下图展示了REST的扩展性:

图8.6 REST的扩展性

RESTful的实现

Go没有为REST提供直接支持,但是因为RESTful是基于HTTP协议实现的,所以我们可以利用net/http包来自己实现,当然需要针对REST做一些改造,REST是根据不同的method来处理相应的资源,目前已经存在的很多自称是REST的应用,其实并没有真正的实现REST,我暂且把这些应用根据实现的method分成几个级别,请看下图:

图8.7 REST的level分级

上图展示了我们目前实现REST的三个level,我们在应用开发的时候也不一定全部按照RESTful的规则全部实现他的方式,因为有些时候完全按照RESTful的方式未必是可行的,RESTful服务充分利用每一个HTTP方法,包括DELETEPUT。可有时,HTTP客户端只能发出GETPOST请求:

  • HTML标准只能通过链接和表单支持GETPOST。在没有Ajax支持的网页浏览器中不能发出PUTDELETE命令

  • 有些防火墙会挡住HTTP PUTDELETE请求,要绕过这个限制,客户端需要把实际的PUTDELETE请求通过 POST 请求穿透过来。RESTful 服务则要负责在收到的 POST 请求中找到原始的 HTTP 方法并还原。

我们现在可以通过POST里面增加隐藏字段_method这种方式可以来模拟PUTDELETE等方式,但是服务器端需要做转换。我现在的项目里面就按照这种方式来做的REST接口。当然Go语言里面完全按照RESTful来实现是很容易的,我们通过下面的例子来说明如何实现RESTful的应用设计。

6. Nginx特点,概念及常见配置

TODO:

7. https(TLS)简介及升级
  • 图解SSL/TLS协议
  • SSL/TLS协议运行机制的概述
  • TLS协议:Transport Layer Security protocol
  • 握手过程:开始加密通信之前,客户端和服务器首先必须建立连接和交换参数,这个过程叫做握手(handshake)。
    • 第一步,爱丽丝给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法。

    • 第二步,鲍勃确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。

    • 第三步,爱丽丝确认数字证书有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给鲍勃。

    • 第四步,鲍勃使用自己的私钥,获取爱丽丝发来的随机数(即Premaster secret)。

    • 第五步,爱丽丝和鲍勃根据约定的加密方法,使用前面的三个随机数,生成"对话密钥"(session key),用来加密接下来的整个对话过程。
  • 如何将一个 HTTP 网站升级到 HTTPS

  • 一、获取证书:证书是一个二进制文件,里面包含经过认证的网站公钥和一些元数据,要从经销商购买。
  • 二、安装证书
  • 三、修改链接:网页加载的 HTTP 资源,要全部改成 HTTPS 链接
    <!-- 改法一 -->
    <script src="https://foo.com/jquery.js"></script>
    <!-- 改法二:根据当前网页的协议,加载相同协议的外部资源,更灵活一些 -->
    <script src="//foo.com/jquery.js"></script>
  • 四、301重定向:修改 Web 服务器的配置文件,使用 301 重定向,将 HTTP 协议的访问导向 HTTPS 协议
  • 五、安全措施

    • 确保浏览器只在使用 HTTPS 时,才发送Cookie。
      网站响应头里面,Set-Cookie字段加上Secure标志即可。
      Set-Cookie: LSID=DQAAAK...Eaem_vYg; Secure
      8. 参考连接
  • https://developer.mozilla.org/en-US/docs/Web/HTTP
  • https://yanlee26.github.io/2018/03/05/HTTP/
打开App,阅读手记
7人推荐
发表评论
随时随地看视频慕课网APP