HTTP请求分析

文章目录

  • HTTP协议
    • HTTP协议特点
    • HTTP请求报文
    • HTTP响应报文
  • HTTP请求方法
    • GET
    • HEAD
    • POST
    • GET 和 POST 比较
    • PATCH 和 PUT 比较
  • 简单请求与预检请求
    • 简单请求
    • 预检请求
  • POST内容编码类型


HTTP协议

HTTP(Hyper Text Transfer Protocol)是一个基于TCP/IP通信协议来传递数据,包括html文件、图像、结果等,即是一个客户端和服务器端请求和应答的标准。

HTTP协议特点

  1. http无连接:限制每次连接只处理一个请求,服务端完成客户端的请求后,即断开连接。(传输速度快,减少不必要的连接,但也意味着每一次访问都要建立一次连接,效率降低)

  2. http无状态:对于事务处理没有记忆能力。每一次请求都是独立的,不记录客户端任何行为。(优点解放服务器,但可能每次请求会传输大量重复的内容信息)

  3. 客户端/服务端模型:客户端支持web浏览器或其他任何客户端,服务器通常是apache或者iis等

  4. 简单快速

  5. 灵活:可以传输任何类型的数据

HTTP请求报文

HTTP请求分析_第1张图片

第一部分:请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本。

第二部分:请求头,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息
从第二行起为请求头部,HOST将指出请求的目的地.User-Agent,服务器端和客户端脚本都能访问它,它是浏览器类型检测逻辑的重要基础.该信息由你的浏览器来定义,并且在每个请求中自动发送等等。

第三部分:空行,请求头部后面的空行是必须的
即使第四部分的请求数据为空,也必须有空行。

第四部分:请求体,可以添加任意的其他数据。

HTTP响应报文

HTTP请求分析_第2张图片

第一部分:状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成。

第二部分:响应,用来说明客户端要使用的一些附加信息。

第三部分:空行,消息报头后面的空行是必须的。

第四部分:响应体,服务器返回给客户端的文本信息。
可以是html、json串等信息。

HTTP请求方法

HTTP1.0定义了三种请求方法:GET、POST、HEAD

HTTP1.1新增了五种请求方法:OPTIONS、PUT、DELETE、TRACE、CONNECT

序号 方法 描述
1 GET GET方法用于使用给定的URI从给定服务器中检索信息,即从指定资源中请求数据。使用GET方法的请求应该只是检索数据,并且不应对数据产生其他影响。
在GET请求的URL中发送查询字符串(名称/值对)。请求体中不会包含请求数据,请求数据放在协议头中。
GET请求是可以缓存的,我们可以从浏览器历史记录中查找到GET请求,还可以把它收藏到书签中;且GET请求有长度限制幂等
2 POST 向服务器提交资源让服务器处理,比如提交表单、上传文件等,可能导致建立新的资源或者对原有资源的修改。
提交的资源放在请求体中。
POST请求永远不会被缓存,且对数据长度没有限制;我们无法从浏览器历史记录中查找到POST请求。非幂等
3 HEAD HEAD方法与GET方法相同,但没有响应体,仅传输状态行和标题部分。
主要用来检查资源或超链接的有效性或是否可以可达、检查网页是否被串改或更新,获取头信息等,特别适用在有限的速度和带宽下。
4 PUT 和post类似,html表单不支持。
PUT方法用于将数据发送到服务器以创建或更新资源,它可以用上传的内容替换目标资源中的所有当前内容。
它会将包含的元素放在所提供的URI下,如果URI指示的是当前资源,则会被改变。如果URI未指示当前资源,则服务器可以使用该URI创建资源。所以put是安全的,幂等。而post可能请求几次创建了几次资源。
5 DELETE 请求服务器删除某资源。和put都具有破坏性,可能被防火墙拦截。如果是https协议,则无需担心。幂等
6 CONNECT 用来建立到给定URI标识的服务器的隧道;它通过简单的TCP / IP隧道更改请求连接,通常实使用解码的HTTP代理来进行SSL编码的通信(HTTPS)。
就是把服务器作为跳板,去访问其他网页然后把数据返回回来,连接成功后,就可以正常的get、post了。
7 OPTIONS 获取http服务器支持的http请求方法,允许客户端查看服务器的性能,比如ajax跨域时的预检等。
8 TRACE 回显服务器收到的请求,主要用于测试或诊断。它回应收到的请求,以便客户可以看到中间服务器进行了哪些(假设任何)进度或增量。一般禁用,防止被恶意攻击或盗取信息。

GET

GET方法用于使用给定的URI从给定服务器中检索信息,即从指定资源中请求数据。使用GET方法的请求应该只是检索数据,并且不应对数据产生其他影响。

在GET请求的URL中发送查询字符串(名称/值对)。请求体中一般不会包含请求数据,请求数据放在协议头中。

  • 参数可见

    GET 方法的参数是明文可见的包含在 URL 当中,所以说敏感信息不建议使用 GET 方法

  • 数据类型只允许ASCII

    GET方法的数据类型只允许是 ASCII 字符,所以 GET 方法不可以传递二进制文件

  • 可以保存书签

    因为GET 方法的参数可见,所以 GET 方法允许被保存书签

  • 可以被缓存

    GET 方法支持缓存,当本次请求允许被缓存时,会将资源存值本地 cache ,在未过期的情况下直接取本地 cache;缓存过期后视情况而定

  • 参数会保留在浏览器历史记录

    可以在浏览器的历史记录中查看到曾经搜索过的关键字信息

  • 请求长度会受限于所使用的浏览器与服务器

    不同的浏览器对于 GET 请求长度的限制也是不同的,注意这是 浏览器 / 服务器(IE、Chrome、Apache、IIS等) 对于长度的限制,而不是 HTTP 协议

HEAD

HEAD方法与GET方法相同,但没有响应体,仅传输状态行和标题部分。

主要用来检查资源或超链接的有效性或是否可以可达、检查网页是否被串改或更新,获取头信息等,特别适用在有限的速度和带宽下。

以Apache tomcat为例(HttpServlet.doHead方法):

    protected void doHead(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        if (DispatcherType.INCLUDE.equals(req.getDispatcherType())) {
            doGet(req, resp);
        } else {
            NoBodyResponse response = new NoBodyResponse(resp);
            doGet(req, response);
            response.setContentLength();
        }
    }

可以看出:HEAD请求中调用的也是GET请求的方法。

POST

GET 和 POST 比较

类型 GET POST
点击返回/刷新按钮 没有影响 数据会重新提交
缓存/添加书签 可以 不可以
历史记录 没有
编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded
multipart/form-data
application/json
text/xml
是否幂等 幂等 非幂等
长度限制 http协议没有限制,但是实际浏览器或服务器有 理论上没有,可能会收到服务器配置或内存限制
数据类型限制 只能ASCII,非ascii都要编码传输 没有限制,允许二进制数据
安全性 数据全部展示在url中,不安全 相比get,通过request body传递数据,比较安全
可见性 可见 不可见

application/x-www-form-urlencoded是浏览器默认的编码格式

PATCH 和 PUT 比较

类型 PATCH PUT
是否幂等 非幂等 幂等
粒度 局部,最小粒度,节约网络带宽 所有

注意:比如更新一个userinfo,包含name,age,sex等多个字段,如果只修改了age,如果用put来更新,则需要把其他没有变更的也要提交到服务器,但是使用patch,则只需要提交age到服务器即可。这都是协议层面来讨论的。 put请求专注于update操作,但是与之相关的是还有这个patch请求,两者虽然都专注于update操作,但是前者put是全局而言,后者patch是局限于某一条件或者范围而言,简单的说就是两者的粒度是不同的。

简单请求与预检请求

简单请求

HTTP 1.0 三个方法:HEAD、GET、POST 默认都属于简单请求

  • 没有自定义报头
  • MIME Type in text/plain、multipart/form-data、application/x-www-form-urlencoded

但是简单请求满足以下条件也可以触发Options请求

  • 带有自定义头信息
  • MIME Type Not in text/plain、multipart/form-data、application/x-www-form-urlencoded

预检请求

一般 HTTP1.1 中的方法请求默认都会触发预检请求

预检请求即在请求之前需要首先由浏览器自发发送Options请求的请求

POST内容编码类型

1. application/x-www-form-urlencoded

这应该是最常见的 POST 提交数据的方式了。浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。

请求类似于下面这样(无关的请求头在本文中都省略掉了):

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

Content-Type 被指定为 application/x-www-form-urlencoded;提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。

2. multipart/form-data

这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件

POST http://www.example.com HTTP/1.1
 
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
 
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
 
Content-Disposition: form-data; name="text"
 
title
 
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
 
Content-Disposition: form-data; name="file"; filename="chrome.png"
 
Content-Type: image/png
 
PNG ... content of chrome.png ...
 
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

这种方式,首先生成了一个 boundary 用于分割不同的字段。然后 Content-Type 里指明了数据是以 mutipart/form-data 来编码,每部分都是以 --boundary 开始,紧接着内容描述信息,然后是回车。可以看到content里面也是键值对的形式传给后台。和第一种的区别在于,第二种的value可以是文件file

3. application/json

很多老牌的服务器为了安全,会选择这种方式。特点是content里面存放的,标准格式的json。也就是序列化的json。

POST http://www.example.com HTTP/1.1
 
Content-Type: application/json; charset=utf-8
 
{"title":"test","sub":[1,2,3]}

4. text/xml

用得很少。

你可能感兴趣的:(http)