• HTTP协议


    1 作用

    HTTP是一个客户端和服务器端请求和应答的标准,设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。由统一资源标识符(URI)来标识HTTP或者HTTPS协议请求的资源。

    由HTTP客户端发起一个请求,创建一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端的请求。一旦收到请求,服务器会向客户端返回一个状态,比如"HTTP/1.1 200 OK",以及返回的内容,如请求的文件、错误消息、或者其它信息。

    2 工作流程

    HTTP 请求/响应的步骤:

    1. 客户端连接到Web服务器:与Web服务器的HTTP端口(默认为80),经过三次握手建立一个TCP套接字连接
    2. 发送HTTP请求:通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成
    3. 服务器接受请求并返回HTTP响应:Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
    4. 释放连接TCP连接:若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
    5. 客户端浏览器解析HTML内容:浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。

    3 HTTP方法

    HTTP/1.1协议中共定义了八种方法(也叫“动作”)来以不同方式操作指定的资源:

    GET:向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。
    HEAD:与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)。
    POST:向指定资源提交数据,请求服务器进行处理。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
    PUT:向指定资源位置上传其最新内容。
    DELETE:请求服务器删除Request-URI所标识的资源。
    TRACE:回显服务器收到的请求,主要用于测试或诊断。
    OPTIONS:这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用'*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
    CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。
    HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。

    4 HTTP方法性质

    HTTP方法的几个性质:

    Safe - 安全

    如果一个方法的语义在本质上是「只读」的,那么这个方法就是安全的。客户端向服务端的资源发起的请求如果使用了是安全的方法,就不应该引起服务端任何的状态变化,因此也是无害的。 此RFC定义,GET, HEAD, OPTIONS 和 TRACE 这几个方法是安全的。

    但是这个定义只是规范,并不能保证方法的实现也是安全的,服务端的实现可能会不符合方法语义,正如上文说过的使用GET修改用户信息的情况。

    引入安全这个概念的目的是为了方便网络爬虫和缓存,以免调用或者缓存某些不安全方法时引起某些意外的后果。

    幂等

    幂等的概念是指同一个请求方法执行多次和仅执行一次的效果完全相同。按照RFC规范,PUT,DELETE和安全方法都是幂等的。同样,这也仅仅是规范,服务端实现是否幂等是无法确保的。
    引入幂等主要是为了处理同一个请求重复发送的情况引入幂等主要是为了处理同一个请求重复发送的情况,比如在请求响应前失去连接,如果方法是幂等的,就可以放心地重发一次请求。这也是浏览器在后退/刷新时遇到POST会给用户提示的原因:POST语义不是幂等的,重复请求可能会带来意想不到的后果。

    可缓存性

    就是一个方法获取的资源是否可以被缓存,此RFC里GET,HEAD和某些情况下的POST都是可缓存的,但是绝大多数的浏览器的实现里仅仅支持GET和HEAD

    5 区别介绍

    get和post

    GET的语义是请求获取指定的资源。GET方法是安全、幂等、可缓存的(除非有 Cache-ControlHeader的约束),GET方法的报文主体没有任何语义
    POST的语义是根据请求负荷(报文主体)对指定的资源做出处理,具体的处理方式视资源类型而不同。POST不安全,不幂等,(大部分实现)不可缓存。

    后退按钮/刷新 无害 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
    书签 可收藏为书签 不可收藏为书签
    缓存 能被缓存 不能缓存
    编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。
    历史 参数保留在浏览器历史中。 参数不会保存在浏览器历史中。
    对数据长度的限制

    是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。

    这个限制是浏览器的限制。

    无限制。
    对数据类型的限制 只允许 ASCII 字符。 没有限制。也允许二进制数据。
    安全性

    与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。

    在发送密码或其他敏感信息时绝不要使用 GET !

    POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。
    可见性 数据在 URL 中对所有人都是可见的。 数据不会显示在 URL 中。

    get和post的区别主要在于:

    1. get使用url传递参数,post则使用相应报文中的相应体中传输数据。GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连
    2. 语义上的定义get是幂等的,post不是幂等的
    3. 浏览器实现上的区别,语义上,get和部分post都是可缓存的,但是实现不同
    4. 服务器的实现上,get也可用于修改数据。

    get和head区别

    get请求指定的页面信息,并返回实体主体
    HEAD方法请求的话,则服务器返回的只是响应标题,而不会返回被请求的文挡,HEAD方法通用于一些搜索引擎

    6 URL和URI

    URI统一资源标识符,用来唯一的标识一个资源。任何一种手段来标识出一个文件就可以。
    URL统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何定位这个资源。互联网上的每个文件都有一个唯一的URL。URL则是使用一个路径来标识一个文件。


    URI一般由三部组成:

    1. 访问资源的命名机制
    2. 存放资源的主机名
    3. 资源自身的名称,由路径表示,着重强调于资源。

    采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等

    URN统一资源命名,是通过名字来标识资源,比如mailto:java-net@java.sun.com。
    URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。

    几乎目前所有的uri都是url

    7 HTTP报文格式

    请求报文

    客户端发送一个HTTP请求到服务器的请求消息包括以下格式:

    1. 请求行:用来说明请求类型、要访问的资源、所使用的HTTP版本.
    2. 请求头部:说明服务器要使用的附加信息
    3. 空行:请求头部后面的空行是必须的,用来分割请求头和空行
    4. 请求数据:请求数据也叫主体,可以添加任意的其他数据。

    HTTP之响应消息Response

    响应报文

    服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息

    HTTP响应也由四个部分组成:

    1. 状态行:状态行、由HTTP协议版本号、状态码、状态消息 三部分组成。
    2. 消息报头:说明客户端要使用的一些附加信息
    3. 空行:必须的,用来分割消息报头和响应正文
    4. 响应正文:任意数据

    8 HTTP协议版本区别

    HTTP/1.1与HTTP/1.0的区别:

    1. HTTP/1.0中,每对请求/ 响应都使用一个新的连接。

      HTTP/1.1则支持持久连接(默认)。

    2. HTTP1.1增加了OPTIONS, PUT, DELETE, TRACE, CONNECT这些Request方法
    3. HTTP/1.1中新增了24个状态响应码

    9 状态码

    1xx:信息状态码,表示成功接收请求,要求客户端继续提交下一次请求才能完成整个处理过程

    • 100:客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分

    2xx:成功状态码,表示成功接收请求并已完成整个处理过程

    • 200:请求已成功,请求所希望的响应头或数据体将随此响应返回。

    3xx:重定向状态码,例如,请求的资源已经移动一个新地址

    • 300: 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。 
    • 301:(永久移动)  请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。 
    • 302:(临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。配合Location 字段 (http1.0 和 http1.1 一样)
    • 303:  允许在post收到 303 的时候向 location将post改为get请求
    • 304:(未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
    • 307: 收到307 表示不允许用户的post改为get向location地址,需要询问用户.

    重定向下的post和get:

    1. post请求遇到 302 时,浏根据rfc要求浏览器必须询问是否需要向收到的重定向链接发送post请求.但是大多数浏览器会讲post改为get请求,向浏览器发送.也就是说post收到302 后,浏览器讲post改为get发送给loacation.但是大多302 又都按照303处理了
    2. 因此,http1.1 增加了303 状态码,表示post 到的地址重定向了,那么浏览器在收到303 的时候,可以讲post改为get.
    3. 307 如上所说
    4. 因此,303 和037 是对302 的一种修补.主要是在一些非幂等的方法时,浏览器必须遵守的.
    5. 302 应该是被丢弃的,但是为了兼容浏览器,这个还是在广泛的使用

    4xx:客户端的请求有错误

    • 400:服务器不理解请求的语法。 
    • 401:请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。 
    • 403:服务器拒绝请求
    • 404:服务器找不到请求的网页。 
    • 410:请求的资源已永久删除,服务器就会返回此响应

    5xx:服务器端出现错误

    • 500:(服务器内部错误)  服务器遇到错误,无法完成请求。
    • 501:服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
    • 503:(服务不可用) 服务器目前无法使用(由于超载或停机维护)
    • 505:服务器不支持请求中所用的 HTTP 协议版本

    10 HTTP字段含义

    Accept:接受的内容类型 Accept: text/plain

    Accept-Charset:设置接受的字符编码 Accept-Charset: utf-8

    Accept-Encoding:设置接受的编码格式 Accept-Encoding: gzip, deflate

    Accept-Datetime:设置接受的版本时间 Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT

    Accept-Language:设置接受的语言 Accept-Language: en-US

    Authorization:设置HTTP身份验证的凭证 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

    Connection:设置当前连接和hop-by-hop协议请求字段列表的控制选项 Connection: keep-alive Connection: Upgrade

    Content-Length 设置请求体的字节长度,描述HTTP消息实体的传输长度,消息实体长度和消息实体的传输长度是有区别,比如说gzip压缩下,消息实体长度是压缩前的长度,消息实体的传输长度是gzip压缩后的长度。

    Cookie 设置服务器使用Set-Cookie发送的http cookie

    Date 设置消息发送的日期和时间

    Host 设置服务器域名和TCP端口号,如果使用的是服务请求标准端口号,端口号可以省略

    User-Agent 用户代理的字符串值

    DNT 请求web应用禁用用户追踪

    11 HTTP缓存相关

    参考文章-HTTP缓存工作流程详解

    11.1 根据超时时间

    Expires http/1.0中定义的header,是最基础的浏览器缓存处理,表示资源在一定时间内从浏览器的缓存中获取资源,不需要请求服务器获取资源,从而达到快速获取资源,缓解服务器压力的目的。

    Cache-Control:设置请求响应链上所有的缓存机制必须遵守的指令 Cache-Control: no-cache

    打开新窗口 如果指定cache-control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器,例如:Cache-control: max-age=5 表示当访问此网页后的5秒内不会去再次访问服务器.
    在地址栏回车 如果值为private或must-revalidate,则只有第一次访问时会访问服务器,以后就不再访问。如果值为no-cache,那么每次都会访问。如果值为max-age,则在过期之前不会重复访问。
    按后退按扭 如果值为private、must-revalidate、max-age,则不会重访问,而如果为no-cache,则每次都重复访问.
    按刷新按扭 无论为何值,都会重复访问.

    Expires 与 Cache-Control的max-age

    Expires采用的是服务器时间来确定何时超时,但是当服务器与客户端存在时间差很大的时候(客户端时间不准)那么Expires的缓存就会不精确

    Cache-Control的max-age则采用的是更新间隔,因此比Expires更加精确一些。

    所以在HTTP 1.1版开始,使用Cache-Control: max-age替代。
    注意:如果max-age和Expires同时存在,则被Cache-Control的max-age覆盖。

    11.2 根据文件修改时间

    Last-Modified 在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是客户端请求的资源,同时有一个Last-Modified的属性标记此文件在服务器端最后被修改的时间。客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会向服务器传送If-Modified-Since报头,询问该时间之后文件是否有被修改过。如果服务器端的资源没有变化,则自动返回 HTTP 304(Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。精确到秒。

    if-modified-since 服务器将缓存文件的缓存时间与请求本地时间戳比较后,如果发现没有改认为此资源可以继续使用,而且不用再次通知客户端被称为 not-modified 所以not- modified的响应码是304 只要客户端收到304响应码就认为没有改变,那么它的缓存将会继续使用,由于发一次新请求就意味着页面缓存时长又可以继续使用。

    但是,当网站内容的修改频度非常高,因为有些内容是动态生成的 以毫秒级别来管理,但是Last-Modified 配合Modified-Since只能精确到秒,因此会存在一个不一致的行为

    Etag 根据文件名和修改时间生成一个字符串,可以标识精确的修改时间到毫秒。配合If-none-match。代替Last-Modified/if-modified-since。但其实两者本质是相同的。

    1. 客户端请求一个页面(A)。
    2. 服务器返回页面A,并在给A加上一个Last-Modified/ETag。
    3. 客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。
    4. 客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
    5. 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。

    在web服务器只有一台的情况,请求内容的唯一性可以由Etag来确定,但是如果是多台web服务器在负载均衡设备下提供对外服务,尽管各web服务器上的组件内容完全一致,但是由于在不同的服务器上inode是不同的,因此对应生成的Etag也是不一样的。在这种情况下,尽管请求的是同一个未发生变化的组件,但是由于Etag的不同,导致Apache服务器不再返回「“304 Not Modified”,而是返回了200 OK和实际的组件内容(尽管事实上内容不曾发生变化),大大浪费了带宽。

    因此分布式中ETAG的生成不能依赖于底层。否则会出现ETAG不一致的情况。

    Last-Modified、Etag和Expires

    使用Last-Modified标识由于在资源未修改时返回的response内容为空,可以节省一点带宽,但是还是逃不掉发一个HTTP请求出去,需要浏览器连接一次服务器端。
    而Expires标识却使得浏览器干脆连HTTP请求都不用发,但是当用户使用F5或者点击Refresh按钮的时候,就算URI设置了Expires,浏览器一样也会发一个HTTP请求给服务器端,所以,Last-Modified还是要用的,而且要和Expires一起用。

    12 cookie 和session

    因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么。

    会话管理就是为了解决这个问题的。主要方式有隐藏域,cookies,与URL重写。用得较多的是后两种

    例如,当需要连续提交两个页面的信息时,当要提交第二个页面的信息时候,因为http无连接性,因此不能够识别第二个页面提交的信息的前半部分

    隐藏域:则是将第一个页面的信息也保存下来,然后在提交的时候,构造出两个页面的信息一起提交。使用hidden属性。也就是在提交的时候额外的提交一些信息,让服务器能够识别出来。

    cookies:cookie是存储key-value对的一个文件,它是由服务器将cookie添加到response里一并返回给客户端,然后客户端会自动把response里的cookie接收下来,并且保存到本地,下次发出请求的时候,就会把cookie附加在request里,服务器在根据request里的cookie遍历搜索是否有与之符合的信息 。 cookie的内容主要包括:名字,值,过期时间,路径和域。

    session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。 当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用。 保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。

    由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写。

    但是session占用服务器的内存。

    13 http和https

    https

    http默认在80端口下使用,传输的信息为明文,也就是直接是应用程序的数据,抓包工具可以直接看到应用程序发送的数据。

    https默认在443端口下使用。信息经过加密

    http通信存在的问题:

    1. 容易被监听

    2. 被伪装

      有服务器伪装成目标服务器

    3. 被篡改

      篡改双方通信

    https则解决了上面的三个问题:

    1. 数据被加密,防止了窃听

    2. 通信双方需要携带证书,因此不会存在伪装

    3. https对数据做了摘要,篡改数据会被感知到.

    https步骤为:

    1. 通过tcp进行三次握手

    2. 浏览器发送自身所支持的加密协议和版本ssl,tls

      包含,版本号,一个随机数,一个SID,如果SID不为空,那么表示之前通信过

    3. 服务器返回选择对应的加密协议和版本,服务器返回证书,证书中有公钥

      一个随机数,一个SID,使用使用的加密协议,证书

    4. 客户端使用根证书验证证书的合法性.

    5. 客户端生成对称秘钥,通过证书中的公钥加密,发送到服务器

    6. 服务器使用私钥解密,获取对称秘钥,使用对称秘钥加密数据

    7. 客户端解密数据,开始通信

  • 相关阅读:
    容灾、备份、存储
    春节前后学习实践的技术领域
    C#高级编程技术复习一
    利用投影制作多边框
    利用循环调用同一个函数
    IOS NSURLRequest(http请求)讲解 ---------赎罪之路
    IOS SQLite基本操作
    数据库三凡式通俗解析(转载)
    数据库设计原则(转载)
    MusicRadio ----------项目分享
  • 原文地址:https://www.cnblogs.com/perfy576/p/8571800.html
Copyright © 2020-2023  润新知