读 HTTP 协议
来源:互联网 发布:mac风扇一直转 编辑:程序博客网 时间:2024/06/05 23:46
文章链接: http://harttle.com/2014/10/01/http.html
超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP) 是互联网上应用最为广泛的一种网络协议。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由 统一资源标识符(Uniform Resource Identifiers,URI) 来标识。
HTTP协议标准是由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)制定的,其中最著名的是RFC 2616,定义了HTTP协议中现今广泛使用的一个版本—HTTP 1.1。
第一个版本的HTTP(HTTP/0.9)用于Internet上的传输原始数据;HTTP/1.0加入了MIME支持、元数据、请求/应答限定符。
对web开发者而言HTTP协议的用法已耳熟能详,本文只记录与web开发相关的HTTP重要细节。
HTTP是一种通用的、无状态的应用层协议,适用于分布式、协同的、超媒体信息系统。通过一些扩展(如请求方法、错误码、头信息),HTTP可用于超文本外的其他用途,例如命名服务器、分布式对象管理。HTTP的特点在于数据表示的类型与协商,允许建立系统时不必考虑数据是如何传输的。
操作
多数HTTP通信由用户代理发起请求,服务器响应该请求。更复杂的情况则可能包括代理、网关和隧道。 代理 是指转发代理,它接受URI请求,重写部分消息,然后把重写过的消息转发至URI标识的服务器。 网关 是指接收代理,它运行在其他服务器之上,需要时可以为背后的服务器翻译请求。 隧道 相当于两个连接的中转站,但不会改变消息。当通信需要通过一个中介时可以使用隧道,即使该中介不理解消息内容。
request chain -------------------------------------->UA -----v----- A -----v----- B -----v----- C -----v----- O <------------------------------------- response chain
除隧道外的通信方都可能会采用内部缓存和处理消息,缓存可以缩短请求/应答链。但并不是所有消息都可以被缓存,缓存行为也在RFC2616中加以定义。
request chain ---------->UA -----v----- A -----v----- B - - - - - - C - - - - - - O <--------- response chain
HTTP通常发生在TCP/IP连接上,默认的TCP端口为80,当然也可以使用别的端口。这不会影响到HTTP实现,HTTP只假设有一个可靠的传输协议。
HTTP/1.1连接应该是持久连接。这不仅能够减小TCP连接的内存、CPU开销,减小了TCP包的数量,同时提供了更短的延迟和及时的错误反馈。此时,请求与应答可以形成管道而不必等上一个连接的关闭。
URI
在HTTP中,URI 是用来标识资源的字符串。
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
HTTP URI 是大小写敏感的,相同的URI应该每个字节都完全相同。除非:
- 端口空。此时相当于默认端口。
- 主机名必须大小写无关。
- 模式名必须大小写无关。
- 绝对路径为空。此时相当于
/
。
HTTP方法
GET
:获取URI制定的信息。HEAD
:同GET
,但服务器不返回消息体。POST
:请求服务器接受请求中包装的实体,将其作为URI标识的资源的附属信息。PUT
:让服务器将请求中包装的实体存储为URI标识位置。DELETE
:让服务器将URI标识的资源删除。TRACE
:调用远程的应用层环回。最终服务器应将收到的消息包装为实体并返回状态码为200的应答。CONNECT
:保留,用作代理。
Request 头
request头部字段如下:
request-header = Accept ; Section 14.1 | Accept-Charset ; Section 14.2 | Accept-Encoding ; Section 14.3 | Accept-Language ; Section 14.4 | Authorization ; Section 14.8 | Expect ; Section 14.20 | From ; Section 14.22 | Host ; Section 14.23 | If-Match ; Section 14.24
Accept
:可接受的应答的媒体类型,可使用通配符*
。Accept: autio/*; q=0.2, autio/basic# 最好是basic音频,如果没有的话任何音频都可以接受(这时我认为质量打了80%的折扣)
Accept-Charset
:可接受的应答的字符集。Accept-Charset: iso-8859-5, unicode-1-1;q=0.8# 最好是iso-8859-5,不过unicode-1-1也还好(80%的质量)
Accept-Encoding
:可接受的应答的内容编码。Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
Accept-Language
:可接受的应答的自然语言集合。Accept-Language: da, en-gb;q=0.8, en;q=0.7
Authorization
:用户想要让服务器给自己授权,通常在接受到401
之后发生。Expect
:客户需要的服务器行为。该字段是逐跳发生的,即代理如不能满足该期望应返回
417
;但请求头是端到端的,该请求仍然必须被转发。From
:该字段应为控制发送请求的HTTP代理(agent)的用户电子邮箱名。Host
:目标主机名与端口,来自URI。If-Match
:与HTTP方法一起用,使得条件性执行该方法。条件为该实体匹配该列表,即没有发生用户所不知道的变化。
在HTTP中,质量值
qvalue
作为协商参数的限定符,表示客户端认为该参数的重要性(权重)。如果一个参数qvalue
为0,表示该参数对客户端来讲是不可接受的。参数之间用,
分隔,参数值与质量值之间用;
分隔。
Response 头
response头部字段如下:
response-header = Accept-Ranges ; Section 14.5 | Age ; Section 14.6 | ETag ; Section 14.19 | Location ; Section 14.30 | Proxy-Authenticate ; Section 14.33 | Retry-After ; Section 14.37 | Server ; Section 14.38 | Vary ; Section 14.44 | WWW-Authenticate ; Section 14.47
Accept-Ranges
:在HTTP/1.1中,客户端可以请求部分的应答(
range
),服务器将根据指定的Range Unit
和range
将实体划分为subrange
返回给客户端。该字段允许服务器指定接受怎样的
range
请求。例如:Accept-Ranges: bytes# 接受的range unit为byte
Age
:生成该response以来,服务器估计已经过去了多少时间。该字段用于缓存机制。Etag
:指定请求变量的当前实体Tag。该字段用来比较来自同一资源的变化的实体。Location
:为完成请求或标识新的资源,服务器用该字段将接收者重定向。此处应指定绝对路径。Proxy-Authenticate
:407
(Proxy Authentication Required)响应必须填写该字段。该字段应指出授权模式和该URI代理的参数。收到该响应后代理应寻找自己的授权证书。该字段只用于当前连接(点到点),不应传到下游的客户端。Retry-After
:用于503
(Service Unavailable)响应。指示客户端服务预期多久不可用。可以是绝对时间,也可以是代表时间间隔的整数(单位为秒)。Server
:原始服务器处理该请求的软件信息。Vary
:指示不可缓存的请求头列表(大小写不敏感)。WWW-Authenticate
:401
(Unauthorized)响应必须填写该字段。同Proxy-Authenticate
,只不过该字段作用于用户代理(User Agent)。
缓存
HTTP常用语信息系统,此时应答缓存可以提高性能。缓存应该保证是正确的,如果一个应答的缓存既非一手的,又不够新,则必须在应答中添加警告。
HTTP/1.1的基本缓存机制只有隐式的缓存指示,在有些系统中需要给出明确的缓存指示。此时要用到缓存控制(Cache-Control)头。
最好的缓存应完全避免从原始服务器发送请求,主要的机制是服务器明确给定应答的过期时间。相反地,服务其可以将过期时间设为过去的时间,以此强制得到最新的请求。过期时间的计算有两种方法:
now - Age Header
,其中Age Header
是生成应答时服务器会设置的字段。age_value
,等于该应答在所有缓存中驻留的时间和,加上所有路径上传输所用的时间。
当然,缓存服务器之间需要通过类似
NTP
的协议来同步他们的时钟。
状态码
以下给出状态码说明,其描述参见wikipedia:HTTP状态码
Status-Code = "100" ; Section 10.1.1: Continue | "101" ; Section 10.1.2: Switching Protocols | "200" ; Section 10.2.1: OK | "201" ; Section 10.2.2: Created | "202" ; Section 10.2.3: Accepted | "203" ; Section 10.2.4: Non-Authoritative Information | "204" ; Section 10.2.5: No Content | "205" ; Section 10.2.6: Reset Content | "206" ; Section 10.2.7: Partial Content | "300" ; Section 10.3.1: Multiple Choices | "301" ; Section 10.3.2: Moved Permanently | "302" ; Section 10.3.3: Found | "303" ; Section 10.3.4: See Other | "304" ; Section 10.3.5: Not Modified | "305" ; Section 10.3.6: Use Proxy | "307" ; Section 10.3.8: Temporary Redirect | "400" ; Section 10.4.1: Bad Request | "401" ; Section 10.4.2: Unauthorized | "402" ; Section 10.4.3: Payment Required | "403" ; Section 10.4.4: Forbidden | "404" ; Section 10.4.5: Not Found | "405" ; Section 10.4.6: Method Not Allowed | "406" ; Section 10.4.7: Not Acceptable | "407" ; Section 10.4.8: Proxy Authentication Required | "408" ; Section 10.4.9: Request Time-out | "409" ; Section 10.4.10: Conflict | "410" ; Section 10.4.11: Gone | "411" ; Section 10.4.12: Length Required | "412" ; Section 10.4.13: Precondition Failed | "413" ; Section 10.4.14: Request Entity Too Large | "414" ; Section 10.4.15: Request-URI Too Large | "415" ; Section 10.4.16: Unsupported Media Type | "416" ; Section 10.4.17: Requested range not satisfiable | "417" ; Section 10.4.18: Expectation Failed | "500" ; Section 10.5.1: Internal Server Error | "501" ; Section 10.5.2: Not Implemented | "502" ; Section 10.5.3: Bad Gateway | "503" ; Section 10.5.4: Service Unavailable | "504" ; Section 10.5.5: Gateway Time-out | "505" ; Section 10.5.6: HTTP Version not supported | extension-code
HTTP表单
在web开发中最常见的莫过于GET和POST,其中GET一般将参数编码在url中(HTTP header)来传递数据;
而POST或PUT数据必须放在消息主体(entity-body)中,这样的数据便是HTTP表单,表单数据的编码方式应在HTTP头中进行设置(Content-Type header字段),常见的编码方式有(HTTP采用MIME框架,编码方式可以是任何MIME类型):
- urlencoded
- multipart
- json
- plain text
- xml
在Web开发中,前三种格式非常常见。HTML中<form>
支持urlencoded
,multipart
,plain text
,通过enctype
属性来进行设置。AJAX中默认的则是JSON编码格式。
urlencoded
HTML中<form>
标签的enctype
属性用来指定表单编码格式,默认为application/x-www-form-urlencoded
,即以下两个表单完全等价。
<form method='post'> <input type="text" name='title'> <input type="text" name='subtitle'> <input type="submit"></form>
<form method='post' enctype='application/x-www-form-urlencoded'> <input type="text" name='title'> <input type="text" name='subtitle'> <input type="submit"></form>
上述表单将会显示为两个文本框和一个提交按钮。我们在文本框中分别写入test
和中国
后,点击提交按钮。产生的HTTP请求可能是这样的:
可以打开Chrome控制台的Network标签,找到这次请求,便可以看到下面的信息。
请求头(这里只给出了Content-Type
字段):
POST http://www.example.com HTTP/1.1Content-Type: application/x-www-form-urlencoded
请求体:
title=test&subtitle=%E4%B8%AD%E5%9B%BD
这里你看到的
%E4%B8%AD%E5%9B%BD
即是中国
按照base64编码(url通用的编码方式)后的结果。可以在Chrome Console中通过decodeURI('%E4%B8%AD%E5%9B%BD')
来解码。
multipart
multipart编码方式则需要设置enctype
为multipart/form-data
。
<form method="post" enctype="multipart/form-data"> <input type="text" name="title" value="harttle"> <input type="file" name="avatar"> <input type="submit"></form>
这里我们还设置了
<input type='text'>
的默认值为harttle
。
该表单将会显示为一个文本框、一个文件按钮、一个提交按钮。然后我们选择一个文件:chrome.png
,点击表单提交后产生的请求可能是这样的:
请求头:
POST http://www.example.com HTTP/1.1Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
请求体:
------WebKitFormBoundaryrGKCBY7qhFd3TrwAContent-Disposition: form-data; name="title"harttle------WebKitFormBoundaryrGKCBY7qhFd3TrwAContent-Disposition: form-data; name="avatar"; filename="chrome.png"Content-Type: image/png ... content of chrome.png ...------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
这便是一个multipart编码的表单。Content-Type
中还包含了boundary
的定义,它用来分隔请求体中的每个字段。正是这一机制,使得请求体中可以包含二进制文件(当然文件中不能包含boundary
)。
除了
application/x-www-form-urlencoded
和multipart/form-data
,HTML的<form>
还支持text/plain
。此外,如果想提交其他编码类型的表单,必须通过AJAX技术,接下来我们介绍一个常用的JSON数据的提交。
json
从JavaScript中提交JSON数据真是再方便不过了,jquery、angularJS等框架都封装了更好用的AJAX方法。例如:
$.post('/xxx', { title: 'test', content: [1,2,3] });
该JavaScript执行后可能生成如下的HTTP请求:
请求头:
POST http://www.example.com HTTP/1.1Content-Type: application/json;charset=utf-8
请求体:
{"title":"test","content":[1,2,3]}
xml
请求头:
POST http://www.example.com HTTP/1.1Content-Type: text/xml
请求体:
<!--?xml version="1.0"?--><methodcall> <methodname>examples.getStateName</methodname> <params> <param> <value><i4>41</i4></value> </params></methodcall>
参考:RTF 2616
- 读 HTTP 协议
- HTTP协议
- http协议
- HTTP协议
- HTTP协议
- HTTP协议
- http协议
- HTTP协议
- HTTP协议
- HTTP协议。。。
- HTTP协议
- HTTP协议
- HTTP协议
- HTTP协议
- HTTP协议
- http协议
- HTTP协议
- http协议
- 黑马程序员---指向函数的指针与返回指针的函数
- 黑马程序员---c语言基础---数组、指针
- java学习笔记——static关键字
- Ruby On Rails 快速创建项目
- HDU 5344 多个数的和异或-思维-(位运算)
- 读 HTTP 协议
- iPhone开发入门系列1(iOS8+Swift版)天天打靶APP学习10-11
- springMVC各个包的详细说明
- 03-树2. List Leaves
- MDP接入
- Ubuntu安装gradle
- java学习笔记——抽象 abstract
- Android Studio如何导入SlidingMenu超详细版
- Rails 项目中安装bootstrap的几个小