HTTP协议请求

什么是HTTP协议请求?

HTTP协议规定,请求从客户端发出,最后服务端响应该请求并返回。也就是说,先从客户端开始建立通信的,服务端在没有接受到请求之前不会发送响应。且HTTP协议自身不对请求和响应之间的通信状态进行保存。

(在进行下一步学习之前首先要了解一下HTTP的消息结构)

HTTP消息结构

HTTP是基于客户端/服务端的构架模型,通过一个可靠的链接在交换消息,是一个无状态的请求/响应协议。

一个HTTP“客户端”是一个应用程序,通过连接到服务器达到向服务器发送一个HTTP或多个HTTP的请求的目的。

一个HTTP“服务器”同样也是一个应用程序,通过接收客户端的请求并向客户端发送HTTP响应数据。

HTTP使用统一资源标识符来传输数据和建立连接。一旦建立连接后,数据消息就通过类似Internet邮件所使用的格式和多用途Internet邮件扩展来传送。

客户端请求消息

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行、请求头部、空行、请求数据

请求报文的一般格式如下图所示:

HTTP协议请求_第1张图片

服务器响应消息

HTTP响应也由四个部分组成:状态行、消息报头、空行、响应正文

HTTP协议请求_第2张图片

HTTP协议的8种请求类型

OPTIONS:

返回服务器针对特定资源所支持的HTTP请求方法。也可以利用向Web服务器发送请求来测试服务器的功能性。允许客户端查看服务器性能。

HEAD:

向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回,这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的源信息。(类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头。)

GET:

向特定的资源发出请求。即请求指定的页面信息,并返回实体主体。

POST:

向指定资源提交数据进行处理请求(eg:提交表单上或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的创建或已有资源的修改。

PUT:

向指定资源位置上传其最新内容。(从客户端向服务器传送的数据取代指定的文档的内容)

DELETE:

请求服务器删除Request-URI所标识的资源。(请求服务器删除指定的页面)

TRACE:

回显服务器收到的请求,主要用于测试或诊断。

CONNECT:

HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

注:管道方式:在等待上一个响应的同时,发送下一个请求。

(虽然HTTP的请求方式有8种,但是实际应用种常用的是GET和POST,其他请求方式都可以通过这两种方式间接来实现。)

HTTP响应头信息

HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。

应答头主要有:

Allow:服务器支持哪些请求方法(如GET、POST等)。

Content Encoding:文档的编码方法。只有在解码之后才可以得到Content-Type头指定的内容类型。用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。

Content-Length:表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。

Content-Type:表示后面的文档属于什么MIME类型。

Date:当前的GMT时间。(可以使用setDateHeader来设置这个头避免转换时间格式的麻烦)

Expires:应该在什么时候认为文档过期,从而不再缓存它。

Last-Modified:文档最后改动的时间。

Location:表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。

Refresh:表示浏览器应该在多久之后刷新文档,以秒计。除了刷新当前文档之外,还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。

注:连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新。

Server:服务器名字(Servlet一般不设置这个值,而是由Web服务器自己设置)

Set-Cookie:设置和页面关联的Cookie。

WWW-Authenticate:客户应该在Authentication头中提供什么类型的授权信息?在包含401状态行的应答中这个头是必需的。

注:Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问。

HTTP状态码

当浏览者访问一个网页时,浏览者的浏览器会向网页所在的服务器发送请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头用以响应浏览器的请求。

常见的HTTP状态码

200-请求成功

301-资源(网页等)被永久转移到其他URL。(什么时URL:即统一资源定位符,它用来表示互联网的某个资源地址,互联网上的每个文件都有唯一的URL,它包含信息指出文件的位置以及浏览器应该怎么处理它。)

404-请求的资源(网页等)不存在。

500-内部服务器错误。

GET和POST的区别(前面提到最常用的两种请求方式是GET和POST,下面对其进行比较)

我们常说的一些区别都是一些表面上的,比如:GET没有POST安全、GET请求时URL的长度是有限制的、GET没有bodyPOSTbody等等。这些都是针对浏览器中的要求, 在使用HTTP作为接口进行传输时,就没有这么多条条框框了,此时GETPOST只是HTTP协议中的两种请求方式,而HTTP协议是基于TCP/IP的应用层协议, 无论GET还是POST,用的都是同一个传输层协议,所以在传输上没有区别。

因此,在用作为接口进行传输时,最大的不同就在于报文格式上的不同了

POST /url HTTP/1.1 \r\n GET /url HTTP/1.1 \r\n

上面所示的分别为POST方法请求的报文第一行和GET请求的报文第一行, 显而易见的区别就是方法名不同。除此以外,就没有那么多要求了,GET也可以有bodyPOST也不一定非要使用body,只要客户端和服务器端确定好规范即可,至于形式则你们随意。只不过现在已经习惯了现有的规则,再去改变有些麻烦,毕竟客户端和服务器端要花时间去探讨具体的对接形式。

由于平时大部分见到的都是基于浏览器的请求,下面我们再看几个常见的问题

  1. 我们前面说,无论是GET请求还是POST请求,其本质都是不安全的,为什么这样说呢?如果仅仅从GET请求的参数在地址栏是可见的,POST是不可见的,那就太肤浅了。 由于HTTP自己本身是一个明文协议,每个HTTP请求和返回的数据在网络上都是明文传播,无论是urlheader还是body。 只要在网络节点捉包,就能获取完整的数据报文,要防止泄密的唯一手段就是使用HTTPS(用SSL协议协商出的密钥加密明文HTTP数据)。

  2. 为什么在浏览器中GET请求方式的url长度有限制呢?这是因为浏览器要对url进行解析,而解析的时候就要分配内存。对于一个字节流的解析,必须分配buffer来保存所有要存储的数据。而url这种东西必须当作一个整体看待,无法一块一块处理,于是就处理一个请求时必须分配一整块足够大的内存。如果url太长,而并发又很高,就容易挤爆服务器的内存。

  3. POST是发送两个请求吗? 上面提到POST请求可以被分为“请求头”和“请求体”两个部分,那这两部分是一起发送出去呢?还是先发“请求头”,再发“请求体”呢? 在HTTP协议中并没有明确说明POST会产生两个数据包。之所以会发两个数据包,则是出于以下考虑:如果服务器先收到“请求头”,则会对其进行校验,如果校验通过,则回复客户端“100 - Continue”,客户端再把”请求体“发给服务器。如果请求被拒了,服务器就回复个400之类的错误,这个交互就终止了。这样做的优点是可以避免浪费带宽传输请求体,但是代价就是会多一次Round Trip。如果刚好请求体的数据也不多,那么一次性全部发给服务器可能反而更好。所以说,这和POST完全没有关系,只是基于两端的一种优化手段罢了。

你可能感兴趣的:(http,服务器,网络)