noteless 头像

HTTP协议简介详解 HTTP协议发展 原理 请求方法 响应状态码 请求头 请求首部 java模拟浏览器客户端服务端

协议简介

协议,自然语言里面就是契约,也是双方或者多方经过协商达成的一致意见;

契约也即类似于合同,自然有甲方123...,乙方123...,哪些能做,哪些不能做;

通信协议,也即是双方通过网络通信必须遵从的一组约定;

计算机网络的本质在于传递数据,协议自然是针对于数据的结构格式以及传送规则的约定;

之前介绍过计算机网络的发展,其中TCP/IP协议栈共分为四层,两个程序端点数据的传输是U字形的

应用层

传输层

网络层

网络接口层

HTTP是工作在应用层的协议,所谓的工作在哪层,只不过是对底层的封装程度而已;

 

HTTP协议是什么

HTTP协议是Tim(计算机发展系列提到过)发明的,也正是他完成了万维网三大基础技术的设计:命名方案(URI),通信协议(HTTP)和用来表示信息的标记语言(HTML);

回过神来仔细想想web的发展过程,web是B/S结构的,浏览器(B)通过网络向服务器(S)请求数据,

有了TCP/IP协议以及Socket编程,你可以很容易的完成服务器与请求方的数据沟通;

但是信息的传递的重点在于信息本身,而不是这一次的数据交换,必须要能够相互理解;

因为单纯的数据交流并没有任何意义,必须有对话的基础,那就是"语言";

就好像你(请求方)在说普通话,水果店老板(服务器)在讲英语,你们从早上交流到晚上可能并没有有效的传递任何信息;

所以HTTP协议就是这样一种用于浏览器客户端与服务器交流的一种"语言";

他规定了对话的语法以及格式,有了HTTP协议,客户端和服务器端就可以相互理解对方,才能达到信息交换的目的;

既然HTTP是为了WEB创造的,自然是请求获取的一个过程,而且当时就是HTML

所以最初他就是这么简单,获取一个名为XXX的HTML文件

GET /index.html

1991年Tim写了一篇关于HTTP的协议的文章,被看做是HTTP/0.9

地址:https://www.w3.org/Protocols/HTTP/AsImplemented.html

HTTP-Hypertext Transfer protocol ,超文本传输协议,他的名字完整的对自己进行了释义:传输超文本HTML文件的协议;

 

HTTP协议的发展

最初的版本,看起来可能比较简陋,他只能单独的请求数据,连是不是请求出错了都无法感知,显然,这不可能持续满足需求;

1996年 HTTP/1.0 版本发布

1.0是相对于0.9的大阔步发展,增加了很多内容,详见RFC1945  https://tools.ietf.org/html/rfc1945

不再限制内容的格式只能是HTML,任何格式都可以;

除了GET还引入了POST 和 HEAD 丰富了浏览器客户端和服务器的交互

HTTP请求和相应的格式信息也更加丰富,还增加了状态码等等内容

1997年1月,HTTP/1.1 版本发布,只比 1.0 版本晚了半年,1.1是1.0的升级优化版,重点在于完善优化

这也是目前一直在用的一个版本

 

HTTP协议的格式

 

HTTP默认的端口号为80,HTTPS的端口号为443,HTTP协议包括请求和响应

 

image

其中CRLF是回车换行

imageimage

imageimage

 

11111111111

此图片来自于<计算机网络> ,首部也就是前面图中的头部 一个意思

请求和响应都包括:行/头部/主体

请求行包括:方法/URL/版本号

响应行包括:版本号/状态码/描述

请求头和响应头都是KEY:VALUE的键值对形式,个数为n

头部可以分成三个部分:请求/响应头字段、通用头字段、实体头字段。

其中通用头字段和实体头字段部分内容也在响应部分有相同的定义。

请求体通常不用,响应体也不一定用;

 

HTTP请求方法

 

HTTP请求方法有下面几种,常用的有GET、POST请求.

GET 请求指定的页面信息,并返回实体主体。
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的资源。
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断,还回测试的请求报文

 

HTTP状态码

三位数字表示,第一位表示类型

1XX   消息,服务器收到请求,需要请求者继续执行操作

2XX  成功,操作被成功接收并处理

3XX  重定向,需要进一步的操作以完成请求

4XX  客户端错误,请求包含语法错误或无法完成请求

5XX  服务器错误,服务器在处理请求的过程中发生了错误

 

100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
 
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
 
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
 
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
 
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 充当网关或代理的服务器,从远端服务器接收到了一个无效的请求
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理

 

 

HTTP头部-通用头字段

请求和响应都会用到的头部字段

  1. Cache-Control  指定请求和响应遵循的缓存机制
  2. Connection 控制不在转发给代理的首部也就是有些首部信息通过他控制删除后转发,另外就是是否持久连接1.1默认持久
  3. Date  报文创建的日期和时间 http1.1使用RFC1123中规定的格式
  4. Pragma  遗留字段  形式唯一  Pragma:no-cache,虽是通用,但仅用于请求,要求所有中间服务器不返回缓存的资源
  5. Trailer 事先说明报文主体之后记录了哪些头字段
  6. Transfer-Encoding  传输报文主体时采用的编码方式
  7. Upgrade  检测HTTP协议以及其他协议是否可以使用更高版本通信,参数还可以指定一个完全不同的通信协议
  8. Via  追踪客户端和服务器之间的请求和响应报文的传输路径
  9. Warning  告知用户一些与缓存相关的问题的警告

 

 

 

HTTP头部-请求头字段

从客户端向服务器端发送请求时使用到的头字段,补充了请求的附加内容,客户端信息,响应内容优先级等信息

 

1.Accept

告知服务器,能够处理的媒体类型以及媒体类型的相对优先级  可使用type/subtype的形式,一次指定多种类型

比如  text/html,text/plain,text/css………

2.Accept-Charset

告知服务器,能够处理的字符集以及字符集的相对优先级

也可以一次指定多个

3.Accept-Encoding

告知服务器,支持的内容编码以及内容编码的相对优先级,可以一次性指定多种内容编码 gzip,compress,deflate,identity

4.Accept-Language

告知服务器,能够处理的自然语言集,比如中文 英文 ,以及自然语言的相对优先级,可以一次性指定多种自然语言集

5.Authorization

告知服务器,认证信息

6.Expect

告知服务器,期望出现的某种特定行为

7.From

告知服务器,电子邮件地址

8.Host

告知服务器,请求资源的主机名以及端口号,Host是请求头字段里面,HTTP1.1唯一一个要求必须有的字段

 

形如If-Xxx的请求头字段,都是条件字段,服务器会判断这个条件,只有条件为真的时候才会执行请求

9.If-Match

告知服务器,匹配资源所用的实体标记ETag的值 如果使用*号,服务器将忽略不在比较

10.If-Modified-Since

告知服务器,指定的日期后资源发生了更新,服务器会接受响应 ,参数为日期时间

11.If-None-Match

与If-Match原理一样,取值相反

12.If-Range

属于附带条件之一 字段值若是跟ETag或者更新日期时间匹配一致,那么作为范围请求处理,否则返回全部资源

13.If-Unmodified-Since

原理同If-Modified 取值相反

14.Max-Forwards

通过TRACE或者OPTIONS,发送包含此字段的请求,以十进制形式指定可经过的服务器最大数目

15.Proxy-Authorization

认证相关

16.Range

对于只获取部分资源的范围请求,告知服务器资源的指定范围,服务器接收Range处理后还会返回206 无法处理则会忽视,返回200以及全部资源

17.Referer

告知服务器请求的原始资源的URI

18.TE

告知服务器,客户端能够处理的响应的传输编码方式以及相对优先级,注意是传输,传输中编码

19.User-Agent

创建请求的浏览器和用户代理名称等信息传达给服务器

 

 

HTTP头部-响应头字段

从服务器端返回响应时用到的头部字段,补充了响应的附加内容

 

1.Accept-Ranges

告知客户端,服务器是否能够处理范围请求,如果不能值为none,Accept-Ranges:none;否则是bytes

2.Age

告知客户端,源服务器在多久前创建了响应,字段值单位为s,如果是缓存服务器值为缓存后的响应再次发起认证到认证完成的时间值,代理创建响应必须加上Age

3.Etag

告知客户端实体标识,可以将资源以字符串形式唯一标识的方式,服务器会给每个资源创建ETag值,资源更新,Etag也需要更新

4.Location

将响应接收方引导至某个请求URI位置不同的资源,基本上字段会配合3XX,几乎所有的浏览器接收到Location响应都会强制尝试对已经提示的信息进行重定向

5.Proxy-authenticate

代理服务器需要的认证信息发送给客户端

6.Retry-After

告知客户端,多久后重新请求,主要配合503或者3xx Redirect响应一起使用

7.Server

告知客户端,服务器上安装的HTTP服务器应用程序信息

8.Vary

源服务器向代理服务器传达对缓存进行控制的信息,

9.WWW-Authenticate

用于HTTP访问认证

 

HTTP头部-实体头字段

针对请求和响应报文的实体部分使用的头字段,用于补充内容的更新时间等与实体相关的信息

1.Allow

通知客户端能够支持Request-URI指定资源的所有HTTP方法,收到不支持的方法请求时,返回405 Method Not Allowed,还会把支持的方法写入首部字段Allow返回

2.Content-Encoding

会告知客户端   服务器 对实体的主体部分选用的内容编码方式,指在不丢失信息的前提下进行压缩

3.Content-Language

告知客户端,实体主体使用的自然语言比如中文 英文

4.Content-Length

实体主体部分的大小,单位字节

5.Content-Location

给出与报文主体部分相对应的URI,和Location不同,本字段表示的是报文主体返回资源对应的URI

6.Content-MD5

MD5生成的值,目的在于检查报文主体传输过程中是否保持完整,客户端通过对报文主体执行相同的MD5算法然后比对,确认传输到达

7.Content-Range

针对范围请求,返回响应时使用的首部字段,告知客户端 作为响应返回的实体的 哪个部分符合范围请求. 字节为单位

8.Content-Type

实体主体内对象的媒体类型,用type/subType设置

9.Expires

资源失效的日期告诉客户端,接收到Expires的响应后会以缓存来应答,指定的时间值之前,响应的副本会一直保存,超过指定时间,缓存服务器会转向源服务器,优先级比Cache-Control max-age低

 

为Cookies服务的头部字段

Set-Cookie  开始状态管理所使用的Cookie信息   响应头字段

Cookie    服务器接收到的Cookie信息   请求头字段

Set-Cookie  字段属性

Name=value   键值对的形式   必须

expires=DATE 有效期,不指定默认为浏览器关闭

path=PATH 服务器上的文件目录作为Cookie的适用对象,不指定默认为当前目录

domain=域名 作为Cookies适用对象的域名,不指定默认为创建Cookie的服务器域名

Secure  仅仅HTTPS下才发送Cookie

HttpOnly 限制,js不能使用Cookie

 

模拟浏览器和服务器原理

说了那么多HTTP协议,其实终究也还只是个信息传递交互的一个格式.

所以说,你只要发送指定格式的数据到服务器,就能像浏览器一样请求数据

只要能够接受请求返回HTTP协议指定的格式的响应,浏览器就能解析数据

网络编程离不开Socket,Socket也是一个IO流,只不过通过Socket实现的是客户端与服务端的IO读写

服务器的I是客户端的O

客户端的I是服务器的O

下面的例子非常的简单,当然也不怎么完善,但是你可以清晰地看到,协议,的作用,

//客户端浏览器
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;



public class Client {

    public static void main(String[] args) throws UnknownHostException, IOException {

        //建立客户端Socket
         Socket s = new Socket("www.baidu.com",80);
         //获取输出流 客户端的输出流也即是服务端的输入流
         //也就是发送数据到服务器
         PrintWriter out = new PrintWriter(s.getOutputStream(),true);
         out.println("GET /error.html HTTP/1.1");
         out.println("Accept: */*");
         out.println("Host: www.baidu.com");
         out.println("Connection: close");
         out.println();
         out.println();
         
         //接收服务器的响应信息
         //客户端的输入流就是服务器输出流
         InputStream in = s.getInputStream();
         //缓冲区 1024
         byte[] buf = new byte[1024];
         int len = in.read(buf);
         //打印信息
         String str =new String(buf,0,len);
         System.out.println(str);
         
         s.close();
         
     }

}

 

image

 

//服务端

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String[] args) throws IOException {

        //服务端socket
         ServerSocket ss = new ServerSocket(8080);
         //等待请求
         Socket s = ss.accept();
         System.out.println(s.getInetAddress().getHostAddress()+".....connected");
         
         //获取输入流打印客户端请求信息
         InputStream in = s.getInputStream();
         
         byte[] buf = new byte[1024];
         
         int len = in.read(buf);
         String text = new String(buf,0,len);
         System.out.println(text);
         
         
         //发送数据到客户端
         PrintWriter out = new PrintWriter(s.getOutputStream(),true);
         
         out.println("<font color='green' size='10'>welcome</font>");
         
         s.close();
         ss.close();
     }

}

 

如果有的浏览器打不开,请用IE浏览器,毕竟就随便输出了一条头部信息等都没有好好搞

image

 

HTTP协议总结:

所谓协议就是有固定格式结构,有约定语义;

大家都基于这种语义进行交流沟通;HTTP协议也是如此,他不关注具体的数据,只关心数据的格式以及语义;

所以只要你发送符合HTTP协议的指定格式的请求数据,你就能得到服务器的响应;

只要你返回符合HTTP协议的指定格式的响应数据,你就能正确发送信息到客户端;

服务器端和浏览器(客户端)通过HTTP这一协议进行数据交互,实现了服务器端与浏览器端的解耦

正是解耦,使得浏览器和服务器技术可以相互独立发展;

 

 

 

posted @ 2018-07-09 19:46  noteless  阅读(1815)  评论(0编辑  收藏  举报