SlideShare una empresa de Scribd logo
1 de 24
HTTP Header的方方面面 Tony Deng http://twitter.com/wolfdeng http://friendfeed.com/tonydeng http://delicious.com/wolf.deng http://wolfchina.blogbus.com
写在前面的话 无论你是做前段还是做后端的工作,都会和HTTP Header打交道。 对HTTP Header的了解和通过HTTP Header来判断和处理问题,应该是作为一个Web开发人员一个必备的基本技能和知识。
什么是HTTP Header HTTP是“Hypertext Transfer Protocol”的缩写,整个万维网都在使用这种协议,几乎你在浏览器里看到的大部分内容都是通过http协议来传输的 HTTP是一个基于请求/响应模型的协议,每次的请求和响应都是能够自描述的。 HTTP Headers是HTTP请求和相应的核心,它承载了关于客户端浏览器,请求页面,服务器等相关的信息。
如何才能看到HTTP Headers 可以使用firefox的插件 Firebug http://getfirebug.com/ https://addons.mozilla.org/zh-CN/firefox/addon/1843/ Live HTTP Headers https://addons.mozilla.org/zh-CN/firefox/addon/3829/
一次正常HTTP请求
Request HTTPHeaders 当你在浏览器地址栏里键入一个url,你的浏览器将会发出类似如下的http请求: POST /v2/rss/network/wolf.deng?src=ffbmext2.1.072 HTTP/1.1 Host: feeds.delicious.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6;ffbmext2.1.072 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Authorization: Basic Y29va2llOmNvb2tpZQ== Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Content-Length: 121 Cookie: delicious_us_production=wKAmdMVbf6Puirvhqyt5EZohOKZSFQLAzT8fG2YbpuCrI58dVgL5PsKgtSoZYweu9iP7uw8yrEgP7E1Mh19STmdk7swRT_Q.Lsy6dygA__2GGz5GOQEbZQilhfYD43vmw7g7sF6vhVJ.zozzgDxB27WmCst.E5NIxU2.a5rZymPwjoVsIZMo6jvIuKwxk6FVQVOzNuR.ioBFtFK8r31tcHqAppaXOey9W5bt2Y9ImIh5eskaw41k3dedlmdiWkWlULkhgQjWcfQBLWMCWvil4d1xCfF_6mdNfEDgPT1ub9pddrBZHEnxJMxeFCJMzRfiCrxLfZnJm.w-; _user=wolf.deng%202.1%201274542193%20-1%201%2069ee445a6e6b9c5e55e7dbedbf8e966a%204Yi4QNm6kG7rtc.eIX_3C8yveFQ-; lt=d; FFDeliciousXT=version=2.0 Pragma: no-cache Cache-Control: no-cache _user=wolf.deng%25202.1%25201274542193%2520-1%25201%252069ee445a6e6b9c5e55e7dbedbf8e966a%25204Yi4QNm6kG7rtc.eIX_3C8yveFQ-
HTTP Request 的结构 第一行被称为“Request Line”,它描述的是这个请求的基本信息,剩下的都是HTTP Headers。
HTTP Request 的结构 被称作“Request-Line”的第一行包含三个部分: “method” 表明这是何种类型的请求. 最常见的请求类型有 GET, POST 和 HEAD. “path” 体现的是主机之后的路径. 例如, 当你请求 “http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/”时 ,  path 就会是 “/tutorials/other/top-20-mysql-best-practices/”. “protocol” 包含有 “HTTP” 和版本号, 现代浏览器都会使用1.1. 剩下的部分每行都是一个“Name:Value”对。 它们包含了各式各样关于请求和你浏览器的信息。例如 “User-Agent“就表明了你浏览器 版本和你所用的操作系统。 “Accept-Encoding“会告诉服务器你的浏览可以接受类似gzip的压缩输出。 这些headers大部分都是可选的,当你去掉这些headers之后,你仍旧可以从服务器收到有效的响应。  HTTP 请求甚至可以被精简成这样子: GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1 Host: net.tutsplus.com
请求类型 详细的请求类型说明,可以看看HTTP协议中的RFC文档 http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3 三种最常见的请求类型是:GET,POST 和 HEAD ,你可能已经熟悉了前两种。 其他还有:OPTIONS,PUT,DELETE,TRACE,CONNECT
GET:获取一个文档 大部分被传输到浏览器的html,images,js,css, … 都是通过GET方法发出请求的。它是获取数据的主要方法。 例如,要获取Nettuts+的文章,http request的第一行通常看起来是这样的: GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1 一旦html加载完成,浏览器将会发送GET 请求去获取图片,就像下面这样: GET /wp-content/themes/tuts_theme/images/header_bg_tall.png HTTP/1.1 表单也可以通过GET方法发送,下面是个例子: <form action="foo.php" method="GET">First Name: <input name="first_name" type="text" />Last Name: <input name="last_name" type="text" /><input name="action" type="submit" value="Submit" /></form> 当这个表单被提交时,HTTP request 就会像这样: GET /foo.php?first_name=John&last_name=Doe&action=Submit HTTP/1.1... 你可以将表单输入通过附加进查询字符串的方式发送至服务器。
POST:发送数据至服务器 尽管你可以通过GET方法将数据附加到url中传送给服务器,但在很多情况下使用POST发送数据给服务器更加合适。通过GET发送大量数据是不现 实的,它有一定的局限性。 用POST请求来发送表单数据是普遍的做法。我们来把上面的例子改造成使用POST方式: <form action="foo.php" method="POST">First Name: <input name="first_name" type="text" />Last Name: <input name="last_name" type="text" /><input name="action" type="submit" value="Submit" /></form> 提交这个表单会创建一个如下的HTTP 请求: POST /foo.php HTTP/1.1Host: localhostUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-us,en;q=0.5Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Connection: keep-aliveReferer: http://localhost/test.phpContent-Type: application/x-www-form-urlencodedContent-Length: 43first_name=John&last_name=Doe&action=Submit 这里有三个需要注意的地方: 第一行的路径已经变为简单的 /foo.php , 已经没了查询字符串。 新增了 Content-Type 和 Content-Lenght头部,它提供了发送信息的相关信息. 所有数据都在headers之后,以查询字符串的形式被发送. POST方式的请求也可用在AJAX,应用程序,cURL … 之上。并且所有的文件上传表单都被要求使用POST方式。
HEAD:接收头部信息 HEAD和GET很相似,只不过HEAD不接受HTTP响应的内容部分。 当你发送了一个HEAD请求,那就意味着你只对HTTP头部感兴趣,而不是 文档本身。 这个方法可以让浏览器判断页面是否被修改过,从而控制缓存。也可判断所请求的文档是否存在。 例如,假如你的网站上有很多链接,那么你就可以简单的给他们分别发送HEAD请求来判断是否存在死链,这比使用GET要快很多。
HTTP Headers 中的 HTTP请求 现在我们来看一些在HTTP headers中常见的HTTP请求信息。 Host 一个HTTP请求会发送至一个特定的IP地址,但是大部分服务器都有在同一IP地址下托管多个网站的能力,那么服务器必须知道浏览器请求的是哪个域 名下的资源。 Host: rlog.cn 这只是基本的主机名,包含域名和子级域名。 User-Agent User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729) 这个头部可以携带如下几条信息: 浏览器名和版本号. 操作系统名和版本号. 默认语言. 这就是某些网站用来收集访客信息的一般手段。例如,你可以判断访客是否在使用手机访问你的网站,然后决定是否将他们引导至一个在低分辨率下表现良好 的移动网站。 Accept-Language Accept-Language: en-us,en;q=0.5 这个信息可以说明用户的默认语言设置。如果网站有不同的语言版本,那么就可以通过这个信息来重定向用户的浏览器。 它可以通过逗号分割来携带多国语言。第一个会是首选的语言,其它语言会携带一个“q”值,来表示用户对该语言的喜好程度(0~1)。 Accept-Encoding Accept-Encoding: gzip,deflate 大部分的现代浏览器都支持gzip压缩,并会把这一信息报告给服务器。这时服务器就会压缩过的HTML发送给浏览器。这可以减少近80%的文件大 小,以节省下载时间和带宽。
Response HTTP Headers 当web服务器接收到之前的请求,会给出类似的响应 HTTP/1.1200 OK Date: Mon, 19 Jul 2010 13:40:03 GMT P3P: policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAiIVDiCONiTELoOTPi OUR DELiSAMiOTRiUNRiPUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV" Last-Modified: Mon, 19 Jul 2010 13:40:03 +0000 Set-Cookie: delicious_us_production=f.RPhmyyeaMTaqrzmogv9WIGhABJwj2ZBXmfzl5LdKHdcuH0Pd0VbMLG3U6mhIJpZaaljQsKbSKdCV1pkYOm4eDHYj6ZHQZ6qBPlsa_nme9T9jDIs5WQlCKi6TSg5em31gME2FrLMivIoYvkugbLMh7QGa4I9W1rtzCcDvKQ.qs618aG_Izt4aBJK11c6TmV_YeW1cwx.Z1NuYmSBT4GDSwqEMrBMWtwB2VN3pYy96cW3rAzsdJqr_kizqLR74WHPXC6d1pSF.iyqb990xzQaDS7iqLmTCWt7bSd9zBfmh3Fd_e1VxPRFSk6Gn_3SiAwYAcv1PVedjk-; expires=Tue, 19-Jul-2011 13:40:03 GMT; path=/; domain=.delicious.com Content-Type: application/rss+xml; charset=utf-8 Cache-Control: private Age: 0 Transfer-Encoding: chunked Connection: keep-alive Server: YTS/1.17.21
http响应结构 第一行被称为“Status Line”,它之后就是HTTP Headers,Headers后面的空行完了就开始输出内容了。
http响应结构 第一个有价值的信息就是协议。目前服务器都会使用 HTTP/1.x 或者 HTTP/1.1。 接下来一个简短的信息代表状态。代码200意味着我们的请求已经发送成功了,服务器将会返回给我们所请求的文档,在头部信息之后。 我们都见过“404”页面。当我向服务器请求一个不存在的路径时,服务器就用用404来代替200响应我们。 余下的响应内容和HTTP请求相似。这些内容是关于服务器软件的,页面/文件何时被修改过,mime type 等等… 同样,这些头部信息也是可选的。
HTTP状态码 完整的HTTP状态码列表 http://en.wikipedia.org/wiki/List_of_HTTP_status_codes http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.1 200 用来表示请求成功. 200 成功 (OK) 前文已经提到,200是用来表示请求成功的。 206 部分内容 (Partial Content) 如果一个应用只请求某范围之内的文件,那么就会返回206. 这通常被用来进行下载管理,断点续传或者文件分块下载。 300 来表示重定向. 302(或307)临时移动(Moved Temporarily) 和 301 永久移动(Moved Permanently) 这两个状态会出现在浏览器重定向时。例如,你使用了类似 bit.ly 的网址缩短服务。这也是它们如何获知谁点击了他们链接的方法。 302和301对于浏览器来说是非常相似的,但对于搜索引擎爬虫就有一些差别。 打个比方,如果你的网站正在维护,那么你就会将客户端浏览器用302 重定向到另外一个地址。搜索引擎爬虫就会在将来重新索引你的页面。 但是如果你使用了301重定向,这就等于你告诉了搜索引擎爬虫:你的网站已经永久的移动 到了新的地址。 400 用来表示请求出现问题. 401 未经授权 (Unauthorized) 403 被禁止(Forbidden) 500 用来表示服务器出现问题. 这个代码通常会在页面脚本崩溃时出现。大部分CGI脚本都不会像PHP那样输出错误信息给浏览器。如果出现了致命的错误,它们只会发送一个500的状态 码。这时需要查看服务器错误日志来排错。
HTTP Headers 中的 HTTP响应 Cache-Control w3.org 的定义是:“The Cache-Control general-header field is used to specify directives which MUST be obeyed by all caching mechanisms along the request/response chain.” 其中“caching mechanisms” 包含一些你ISP可能会用到的 网关和代理信息。 例如: Cache-Control: max-age=3600, public “public”意味着这个响应可以被任何人缓存,“max-age” 则表明了该缓存有效的秒数。允许你的网站被缓存降大大减少下载时间和带宽,同时也提高的浏览器的载入速度。 也可以通过设置 “no-cache”  指令来禁止缓存: Cache-Control: no-cache  更多详情请参见w3.org。 Content-Type 这个头部包含了文档的”mime-type”。浏览器将会依据该参数决定如何对文档进行解析。例如,一个html页面(或者有html输出的php页面)将会返回这样的东西: Content-Type: text/html; charset=UTF-8 ‘text’ 是文档类型,‘html’则是文档子类型。 这个头部还包括了更多信息,例如 charset。 如果是一个图片,将会发送这样的响应: Content-Type: image/gif 浏览器可以通过mime-type来决定使用外部程序还是自身扩展来打开该文档。如下的例子降调用Adobe Reader: Content-Type: application/pdf 直接载入,Apache通常会自动判断文档的mime-type并且添加合适的信息到头部去。并且大部分浏览器都有一定程度的容错,在头部未提供或 者错误提供该信息的情况下它会去自动检测mime-type。 你可以在这里找到一个常用mime-type列表。
HTTP Headers 中的 HTTP响应 Content-Disposition 这个头部信息将告诉浏览器打开一个文件下载窗口,而不是试图解析该响应的内容。例如: Content-Disposition: attachment; filename="download.zip" 他会导致浏览器出现这样的对话框: 注意,适合它的Content-Type头信息同时也会被发送 Content-Type: application/zipContent-Disposition: attachment; filename="download.zip"
HTTP Headers 中的 HTTP响应 Content-Length 当内容将要被传输到浏览器时,服务器可以通过该头部告知浏览器将要传送文件的大小(bytes)。 Content-Length: 89123 对于文件下载来说这个信息相当的有用。这就是为什么浏览器知道下载进度的原因。 现在,我将Content-Length头部注释掉: 结果就变成了这样: 这个浏览器只会告诉你已下载了多少,但不会告诉你总共需要下载多少。而且进度条也不会显示进度。
HTTP Headers 中的 HTTP响应 Etag 这是另一个为缓存而产生的头部信息。它看起来会是这样: Etag: "pub1259380237;gz" 服务器可能会将该信息和每个被发送文件一起响应给浏览器。该值可以包含文档的最后修改日期,文件大小或者文件校验和。浏览 会把它和所接收到的文档一起缓存。下一次当浏览器再次请求同一文件时将会发送如下的HTTP请求: If-None-Match: "pub1259380237;gz" 如果所请求的文档Etag值和它一致,服务器将会发送304状态码,而不是2oo。并且不返回内容。浏览器此时就会从缓存加载该文件。 Last-Modified 顾名思义,这个头部信息用GMT格式表明了文档的最后修改时间: Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT 它提供了另一种缓存机制。浏览器可能会发送这样的请求: If-Modified-Since: Sat, 28 Nov 2009 06:38:19 GMT
HTTP Headers 中的 HTTP响应 Location 这个头部是用来重定向的。如果响应代码为 301 或者 302 ,服务器就必须发送该头部。例如,当你访问 http://www.nettuts.com 时浏览器就会收到如下的响应: HTTP/1.x 301 Moved Permanently...Location: http://net.tutsplus.com/... 在PHP中你可以通过这种方式对访客重定向:header('Location: http://net.tutsplus.com/'); 默认会发送302状态码,如果你想发送301,就这样写: header('Location: http://net.tutsplus.com/', true, 301); Set-Cookie 当一个网站需要设置或者更新你浏览的cookie信息时,它就会使用这样的头部: Set-Cookie: skin=noskin; path=/; domain=.amazon.com; expires=Sun, 29-Nov-2009 21:42:28 GMTSet-Cookie: session-id=120-7333518-8165026; path=/; domain=.amazon.com; expires=Sat Feb 27 08:00:00 2010 GMT 每个cookie会作为单独的一条头部信息。注意,通过js设置cookie将不会体现在HTTP头中。 在PHP中,你可以通过setcookie()函 数来设置cookie,PHP会发送合适的HTTP 头。 setcookie("TestCookie", "foobar"); 它会发送这样的头信息: Set-Cookie: TestCookie=foobar 如果未指定到期时间,cookie就会在浏览器关闭后被删除。
HTTP Headers 中的 HTTP响应 WWW-Authenticate 一个网站可能会通过HTTP发送这个头部信息来验证用户。当浏览器看到头部有这个响应时就会打开一个弹出窗。 WWW-Authenticate: Basic realm="Restricted Area" 它会看起来像这样: Content-Encoding 这个头部通常会在返回内容被压缩时设置。 Content-Encoding: gzip
参考 http://css9.net/all-about-http-headers/ http://net.tutsplus.com/tutorials/other/http-headers-for-dummies/ http://www.w3.org/Protocols/rfc2616/rfc2616.html http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.3 http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.2

Más contenido relacionado

Similar a Http header的方方面面

2014 database - course 1 - www introduction
2014 database - course 1 - www introduction2014 database - course 1 - www introduction
2014 database - course 1 - www introduction
Hung-yu Lin
 

Similar a Http header的方方面面 (20)

KMUTNB - Internet Programming 2/7
KMUTNB - Internet Programming 2/7KMUTNB - Internet Programming 2/7
KMUTNB - Internet Programming 2/7
 
WWW and HTTP
WWW and HTTPWWW and HTTP
WWW and HTTP
 
Starting With Php
Starting With PhpStarting With Php
Starting With Php
 
PHP
PHPPHP
PHP
 
Demystifying REST
Demystifying RESTDemystifying REST
Demystifying REST
 
HTTP fundamentals for developers
HTTP fundamentals for developersHTTP fundamentals for developers
HTTP fundamentals for developers
 
HTTP Basics Demo
HTTP Basics DemoHTTP Basics Demo
HTTP Basics Demo
 
PHP Training: Module 1
PHP Training: Module 1PHP Training: Module 1
PHP Training: Module 1
 
Under the Covers with the Web
Under the Covers with the WebUnder the Covers with the Web
Under the Covers with the Web
 
Revisiting HTTP/2
Revisiting HTTP/2Revisiting HTTP/2
Revisiting HTTP/2
 
Intro to-php-19 jun10
Intro to-php-19 jun10Intro to-php-19 jun10
Intro to-php-19 jun10
 
A Holistic View of Website Performance
A Holistic View of Website PerformanceA Holistic View of Website Performance
A Holistic View of Website Performance
 
RESTful design
RESTful designRESTful design
RESTful design
 
Introduction to Web Technology
Introduction to Web TechnologyIntroduction to Web Technology
Introduction to Web Technology
 
How the web works june 2010
How the web works june 2010How the web works june 2010
How the web works june 2010
 
20190516 web security-basic
20190516 web security-basic20190516 web security-basic
20190516 web security-basic
 
Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018
Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018
Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018
 
Leverage HTTP to deliver cacheable websites - Thijs Feryn - Codemotion Rome 2018
Leverage HTTP to deliver cacheable websites - Thijs Feryn - Codemotion Rome 2018Leverage HTTP to deliver cacheable websites - Thijs Feryn - Codemotion Rome 2018
Leverage HTTP to deliver cacheable websites - Thijs Feryn - Codemotion Rome 2018
 
Let’s push the assets to the front i.e. a few words about HTTP2
Let’s push the assets to the front i.e. a few words about HTTP2Let’s push the assets to the front i.e. a few words about HTTP2
Let’s push the assets to the front i.e. a few words about HTTP2
 
2014 database - course 1 - www introduction
2014 database - course 1 - www introduction2014 database - course 1 - www introduction
2014 database - course 1 - www introduction
 

Más de Tony Deng

《我们如何工作》—质量保障
《我们如何工作》—质量保障《我们如何工作》—质量保障
《我们如何工作》—质量保障
Tony Deng
 
《我们如何工作》- 产品经理和工程师如何有效沟通
《我们如何工作》- 产品经理和工程师如何有效沟通《我们如何工作》- 产品经理和工程师如何有效沟通
《我们如何工作》- 产品经理和工程师如何有效沟通
Tony Deng
 
技术债务的形成
技术债务的形成技术债务的形成
技术债务的形成
Tony Deng
 
我们不了解的计算机世界(二)
我们不了解的计算机世界(二)我们不了解的计算机世界(二)
我们不了解的计算机世界(二)
Tony Deng
 
我们不了解的计算机世界(一)--Unix目录结构的来历
我们不了解的计算机世界(一)--Unix目录结构的来历我们不了解的计算机世界(一)--Unix目录结构的来历
我们不了解的计算机世界(一)--Unix目录结构的来历
Tony Deng
 
实时任务调度
实时任务调度实时任务调度
实时任务调度
Tony Deng
 
节约内存:Instagram的redis实践
节约内存:Instagram的redis实践节约内存:Instagram的redis实践
节约内存:Instagram的redis实践
Tony Deng
 

Más de Tony Deng (20)

一页纸项目管理
一页纸项目管理一页纸项目管理
一页纸项目管理
 
Docker at the gate
Docker at the gateDocker at the gate
Docker at the gate
 
《我们如何工作》—质量保障
《我们如何工作》—质量保障《我们如何工作》—质量保障
《我们如何工作》—质量保障
 
《我们如何工作》- 产品经理和工程师如何有效沟通
《我们如何工作》- 产品经理和工程师如何有效沟通《我们如何工作》- 产品经理和工程师如何有效沟通
《我们如何工作》- 产品经理和工程师如何有效沟通
 
我们为何工作--找到正确的工作方式
我们为何工作--找到正确的工作方式我们为何工作--找到正确的工作方式
我们为何工作--找到正确的工作方式
 
SDN介绍
SDN介绍SDN介绍
SDN介绍
 
漫谈职业规划
漫谈职业规划漫谈职业规划
漫谈职业规划
 
一次Http请求过程分析
一次Http请求过程分析一次Http请求过程分析
一次Http请求过程分析
 
图解Git
图解Git图解Git
图解Git
 
一次Code review引发的思考
一次Code review引发的思考一次Code review引发的思考
一次Code review引发的思考
 
My sql迁移总结
My sql迁移总结My sql迁移总结
My sql迁移总结
 
一次项目的探险旅程
一次项目的探险旅程一次项目的探险旅程
一次项目的探险旅程
 
Scrum敏捷开发模型
Scrum敏捷开发模型Scrum敏捷开发模型
Scrum敏捷开发模型
 
Shoutv 冯晓东
Shoutv 冯晓东Shoutv 冯晓东
Shoutv 冯晓东
 
技术债务的形成
技术债务的形成技术债务的形成
技术债务的形成
 
我们不了解的计算机世界(二)
我们不了解的计算机世界(二)我们不了解的计算机世界(二)
我们不了解的计算机世界(二)
 
HBase
HBaseHBase
HBase
 
我们不了解的计算机世界(一)--Unix目录结构的来历
我们不了解的计算机世界(一)--Unix目录结构的来历我们不了解的计算机世界(一)--Unix目录结构的来历
我们不了解的计算机世界(一)--Unix目录结构的来历
 
实时任务调度
实时任务调度实时任务调度
实时任务调度
 
节约内存:Instagram的redis实践
节约内存:Instagram的redis实践节约内存:Instagram的redis实践
节约内存:Instagram的redis实践
 

Http header的方方面面

  • 1. HTTP Header的方方面面 Tony Deng http://twitter.com/wolfdeng http://friendfeed.com/tonydeng http://delicious.com/wolf.deng http://wolfchina.blogbus.com
  • 2. 写在前面的话 无论你是做前段还是做后端的工作,都会和HTTP Header打交道。 对HTTP Header的了解和通过HTTP Header来判断和处理问题,应该是作为一个Web开发人员一个必备的基本技能和知识。
  • 3. 什么是HTTP Header HTTP是“Hypertext Transfer Protocol”的缩写,整个万维网都在使用这种协议,几乎你在浏览器里看到的大部分内容都是通过http协议来传输的 HTTP是一个基于请求/响应模型的协议,每次的请求和响应都是能够自描述的。 HTTP Headers是HTTP请求和相应的核心,它承载了关于客户端浏览器,请求页面,服务器等相关的信息。
  • 4. 如何才能看到HTTP Headers 可以使用firefox的插件 Firebug http://getfirebug.com/ https://addons.mozilla.org/zh-CN/firefox/addon/1843/ Live HTTP Headers https://addons.mozilla.org/zh-CN/firefox/addon/3829/
  • 6. Request HTTPHeaders 当你在浏览器地址栏里键入一个url,你的浏览器将会发出类似如下的http请求: POST /v2/rss/network/wolf.deng?src=ffbmext2.1.072 HTTP/1.1 Host: feeds.delicious.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6;ffbmext2.1.072 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Authorization: Basic Y29va2llOmNvb2tpZQ== Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Content-Length: 121 Cookie: delicious_us_production=wKAmdMVbf6Puirvhqyt5EZohOKZSFQLAzT8fG2YbpuCrI58dVgL5PsKgtSoZYweu9iP7uw8yrEgP7E1Mh19STmdk7swRT_Q.Lsy6dygA__2GGz5GOQEbZQilhfYD43vmw7g7sF6vhVJ.zozzgDxB27WmCst.E5NIxU2.a5rZymPwjoVsIZMo6jvIuKwxk6FVQVOzNuR.ioBFtFK8r31tcHqAppaXOey9W5bt2Y9ImIh5eskaw41k3dedlmdiWkWlULkhgQjWcfQBLWMCWvil4d1xCfF_6mdNfEDgPT1ub9pddrBZHEnxJMxeFCJMzRfiCrxLfZnJm.w-; _user=wolf.deng%202.1%201274542193%20-1%201%2069ee445a6e6b9c5e55e7dbedbf8e966a%204Yi4QNm6kG7rtc.eIX_3C8yveFQ-; lt=d; FFDeliciousXT=version=2.0 Pragma: no-cache Cache-Control: no-cache _user=wolf.deng%25202.1%25201274542193%2520-1%25201%252069ee445a6e6b9c5e55e7dbedbf8e966a%25204Yi4QNm6kG7rtc.eIX_3C8yveFQ-
  • 7. HTTP Request 的结构 第一行被称为“Request Line”,它描述的是这个请求的基本信息,剩下的都是HTTP Headers。
  • 8. HTTP Request 的结构 被称作“Request-Line”的第一行包含三个部分: “method” 表明这是何种类型的请求. 最常见的请求类型有 GET, POST 和 HEAD. “path” 体现的是主机之后的路径. 例如, 当你请求 “http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/”时 , path 就会是 “/tutorials/other/top-20-mysql-best-practices/”. “protocol” 包含有 “HTTP” 和版本号, 现代浏览器都会使用1.1. 剩下的部分每行都是一个“Name:Value”对。 它们包含了各式各样关于请求和你浏览器的信息。例如 “User-Agent“就表明了你浏览器 版本和你所用的操作系统。 “Accept-Encoding“会告诉服务器你的浏览可以接受类似gzip的压缩输出。 这些headers大部分都是可选的,当你去掉这些headers之后,你仍旧可以从服务器收到有效的响应。 HTTP 请求甚至可以被精简成这样子: GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1 Host: net.tutsplus.com
  • 9. 请求类型 详细的请求类型说明,可以看看HTTP协议中的RFC文档 http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3 三种最常见的请求类型是:GET,POST 和 HEAD ,你可能已经熟悉了前两种。 其他还有:OPTIONS,PUT,DELETE,TRACE,CONNECT
  • 10. GET:获取一个文档 大部分被传输到浏览器的html,images,js,css, … 都是通过GET方法发出请求的。它是获取数据的主要方法。 例如,要获取Nettuts+的文章,http request的第一行通常看起来是这样的: GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1 一旦html加载完成,浏览器将会发送GET 请求去获取图片,就像下面这样: GET /wp-content/themes/tuts_theme/images/header_bg_tall.png HTTP/1.1 表单也可以通过GET方法发送,下面是个例子: <form action="foo.php" method="GET">First Name: <input name="first_name" type="text" />Last Name: <input name="last_name" type="text" /><input name="action" type="submit" value="Submit" /></form> 当这个表单被提交时,HTTP request 就会像这样: GET /foo.php?first_name=John&last_name=Doe&action=Submit HTTP/1.1... 你可以将表单输入通过附加进查询字符串的方式发送至服务器。
  • 11. POST:发送数据至服务器 尽管你可以通过GET方法将数据附加到url中传送给服务器,但在很多情况下使用POST发送数据给服务器更加合适。通过GET发送大量数据是不现 实的,它有一定的局限性。 用POST请求来发送表单数据是普遍的做法。我们来把上面的例子改造成使用POST方式: <form action="foo.php" method="POST">First Name: <input name="first_name" type="text" />Last Name: <input name="last_name" type="text" /><input name="action" type="submit" value="Submit" /></form> 提交这个表单会创建一个如下的HTTP 请求: POST /foo.php HTTP/1.1Host: localhostUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-us,en;q=0.5Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Connection: keep-aliveReferer: http://localhost/test.phpContent-Type: application/x-www-form-urlencodedContent-Length: 43first_name=John&last_name=Doe&action=Submit 这里有三个需要注意的地方: 第一行的路径已经变为简单的 /foo.php , 已经没了查询字符串。 新增了 Content-Type 和 Content-Lenght头部,它提供了发送信息的相关信息. 所有数据都在headers之后,以查询字符串的形式被发送. POST方式的请求也可用在AJAX,应用程序,cURL … 之上。并且所有的文件上传表单都被要求使用POST方式。
  • 12. HEAD:接收头部信息 HEAD和GET很相似,只不过HEAD不接受HTTP响应的内容部分。 当你发送了一个HEAD请求,那就意味着你只对HTTP头部感兴趣,而不是 文档本身。 这个方法可以让浏览器判断页面是否被修改过,从而控制缓存。也可判断所请求的文档是否存在。 例如,假如你的网站上有很多链接,那么你就可以简单的给他们分别发送HEAD请求来判断是否存在死链,这比使用GET要快很多。
  • 13. HTTP Headers 中的 HTTP请求 现在我们来看一些在HTTP headers中常见的HTTP请求信息。 Host 一个HTTP请求会发送至一个特定的IP地址,但是大部分服务器都有在同一IP地址下托管多个网站的能力,那么服务器必须知道浏览器请求的是哪个域 名下的资源。 Host: rlog.cn 这只是基本的主机名,包含域名和子级域名。 User-Agent User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729) 这个头部可以携带如下几条信息: 浏览器名和版本号. 操作系统名和版本号. 默认语言. 这就是某些网站用来收集访客信息的一般手段。例如,你可以判断访客是否在使用手机访问你的网站,然后决定是否将他们引导至一个在低分辨率下表现良好 的移动网站。 Accept-Language Accept-Language: en-us,en;q=0.5 这个信息可以说明用户的默认语言设置。如果网站有不同的语言版本,那么就可以通过这个信息来重定向用户的浏览器。 它可以通过逗号分割来携带多国语言。第一个会是首选的语言,其它语言会携带一个“q”值,来表示用户对该语言的喜好程度(0~1)。 Accept-Encoding Accept-Encoding: gzip,deflate 大部分的现代浏览器都支持gzip压缩,并会把这一信息报告给服务器。这时服务器就会压缩过的HTML发送给浏览器。这可以减少近80%的文件大 小,以节省下载时间和带宽。
  • 14. Response HTTP Headers 当web服务器接收到之前的请求,会给出类似的响应 HTTP/1.1200 OK Date: Mon, 19 Jul 2010 13:40:03 GMT P3P: policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAiIVDiCONiTELoOTPi OUR DELiSAMiOTRiUNRiPUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV" Last-Modified: Mon, 19 Jul 2010 13:40:03 +0000 Set-Cookie: delicious_us_production=f.RPhmyyeaMTaqrzmogv9WIGhABJwj2ZBXmfzl5LdKHdcuH0Pd0VbMLG3U6mhIJpZaaljQsKbSKdCV1pkYOm4eDHYj6ZHQZ6qBPlsa_nme9T9jDIs5WQlCKi6TSg5em31gME2FrLMivIoYvkugbLMh7QGa4I9W1rtzCcDvKQ.qs618aG_Izt4aBJK11c6TmV_YeW1cwx.Z1NuYmSBT4GDSwqEMrBMWtwB2VN3pYy96cW3rAzsdJqr_kizqLR74WHPXC6d1pSF.iyqb990xzQaDS7iqLmTCWt7bSd9zBfmh3Fd_e1VxPRFSk6Gn_3SiAwYAcv1PVedjk-; expires=Tue, 19-Jul-2011 13:40:03 GMT; path=/; domain=.delicious.com Content-Type: application/rss+xml; charset=utf-8 Cache-Control: private Age: 0 Transfer-Encoding: chunked Connection: keep-alive Server: YTS/1.17.21
  • 15. http响应结构 第一行被称为“Status Line”,它之后就是HTTP Headers,Headers后面的空行完了就开始输出内容了。
  • 16. http响应结构 第一个有价值的信息就是协议。目前服务器都会使用 HTTP/1.x 或者 HTTP/1.1。 接下来一个简短的信息代表状态。代码200意味着我们的请求已经发送成功了,服务器将会返回给我们所请求的文档,在头部信息之后。 我们都见过“404”页面。当我向服务器请求一个不存在的路径时,服务器就用用404来代替200响应我们。 余下的响应内容和HTTP请求相似。这些内容是关于服务器软件的,页面/文件何时被修改过,mime type 等等… 同样,这些头部信息也是可选的。
  • 17. HTTP状态码 完整的HTTP状态码列表 http://en.wikipedia.org/wiki/List_of_HTTP_status_codes http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.1 200 用来表示请求成功. 200 成功 (OK) 前文已经提到,200是用来表示请求成功的。 206 部分内容 (Partial Content) 如果一个应用只请求某范围之内的文件,那么就会返回206. 这通常被用来进行下载管理,断点续传或者文件分块下载。 300 来表示重定向. 302(或307)临时移动(Moved Temporarily) 和 301 永久移动(Moved Permanently) 这两个状态会出现在浏览器重定向时。例如,你使用了类似 bit.ly 的网址缩短服务。这也是它们如何获知谁点击了他们链接的方法。 302和301对于浏览器来说是非常相似的,但对于搜索引擎爬虫就有一些差别。 打个比方,如果你的网站正在维护,那么你就会将客户端浏览器用302 重定向到另外一个地址。搜索引擎爬虫就会在将来重新索引你的页面。 但是如果你使用了301重定向,这就等于你告诉了搜索引擎爬虫:你的网站已经永久的移动 到了新的地址。 400 用来表示请求出现问题. 401 未经授权 (Unauthorized) 403 被禁止(Forbidden) 500 用来表示服务器出现问题. 这个代码通常会在页面脚本崩溃时出现。大部分CGI脚本都不会像PHP那样输出错误信息给浏览器。如果出现了致命的错误,它们只会发送一个500的状态 码。这时需要查看服务器错误日志来排错。
  • 18. HTTP Headers 中的 HTTP响应 Cache-Control w3.org 的定义是:“The Cache-Control general-header field is used to specify directives which MUST be obeyed by all caching mechanisms along the request/response chain.” 其中“caching mechanisms” 包含一些你ISP可能会用到的 网关和代理信息。 例如: Cache-Control: max-age=3600, public “public”意味着这个响应可以被任何人缓存,“max-age” 则表明了该缓存有效的秒数。允许你的网站被缓存降大大减少下载时间和带宽,同时也提高的浏览器的载入速度。 也可以通过设置 “no-cache”  指令来禁止缓存: Cache-Control: no-cache 更多详情请参见w3.org。 Content-Type 这个头部包含了文档的”mime-type”。浏览器将会依据该参数决定如何对文档进行解析。例如,一个html页面(或者有html输出的php页面)将会返回这样的东西: Content-Type: text/html; charset=UTF-8 ‘text’ 是文档类型,‘html’则是文档子类型。 这个头部还包括了更多信息,例如 charset。 如果是一个图片,将会发送这样的响应: Content-Type: image/gif 浏览器可以通过mime-type来决定使用外部程序还是自身扩展来打开该文档。如下的例子降调用Adobe Reader: Content-Type: application/pdf 直接载入,Apache通常会自动判断文档的mime-type并且添加合适的信息到头部去。并且大部分浏览器都有一定程度的容错,在头部未提供或 者错误提供该信息的情况下它会去自动检测mime-type。 你可以在这里找到一个常用mime-type列表。
  • 19. HTTP Headers 中的 HTTP响应 Content-Disposition 这个头部信息将告诉浏览器打开一个文件下载窗口,而不是试图解析该响应的内容。例如: Content-Disposition: attachment; filename="download.zip" 他会导致浏览器出现这样的对话框: 注意,适合它的Content-Type头信息同时也会被发送 Content-Type: application/zipContent-Disposition: attachment; filename="download.zip"
  • 20. HTTP Headers 中的 HTTP响应 Content-Length 当内容将要被传输到浏览器时,服务器可以通过该头部告知浏览器将要传送文件的大小(bytes)。 Content-Length: 89123 对于文件下载来说这个信息相当的有用。这就是为什么浏览器知道下载进度的原因。 现在,我将Content-Length头部注释掉: 结果就变成了这样: 这个浏览器只会告诉你已下载了多少,但不会告诉你总共需要下载多少。而且进度条也不会显示进度。
  • 21. HTTP Headers 中的 HTTP响应 Etag 这是另一个为缓存而产生的头部信息。它看起来会是这样: Etag: "pub1259380237;gz" 服务器可能会将该信息和每个被发送文件一起响应给浏览器。该值可以包含文档的最后修改日期,文件大小或者文件校验和。浏览 会把它和所接收到的文档一起缓存。下一次当浏览器再次请求同一文件时将会发送如下的HTTP请求: If-None-Match: "pub1259380237;gz" 如果所请求的文档Etag值和它一致,服务器将会发送304状态码,而不是2oo。并且不返回内容。浏览器此时就会从缓存加载该文件。 Last-Modified 顾名思义,这个头部信息用GMT格式表明了文档的最后修改时间: Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT 它提供了另一种缓存机制。浏览器可能会发送这样的请求: If-Modified-Since: Sat, 28 Nov 2009 06:38:19 GMT
  • 22. HTTP Headers 中的 HTTP响应 Location 这个头部是用来重定向的。如果响应代码为 301 或者 302 ,服务器就必须发送该头部。例如,当你访问 http://www.nettuts.com 时浏览器就会收到如下的响应: HTTP/1.x 301 Moved Permanently...Location: http://net.tutsplus.com/... 在PHP中你可以通过这种方式对访客重定向:header('Location: http://net.tutsplus.com/'); 默认会发送302状态码,如果你想发送301,就这样写: header('Location: http://net.tutsplus.com/', true, 301); Set-Cookie 当一个网站需要设置或者更新你浏览的cookie信息时,它就会使用这样的头部: Set-Cookie: skin=noskin; path=/; domain=.amazon.com; expires=Sun, 29-Nov-2009 21:42:28 GMTSet-Cookie: session-id=120-7333518-8165026; path=/; domain=.amazon.com; expires=Sat Feb 27 08:00:00 2010 GMT 每个cookie会作为单独的一条头部信息。注意,通过js设置cookie将不会体现在HTTP头中。 在PHP中,你可以通过setcookie()函 数来设置cookie,PHP会发送合适的HTTP 头。 setcookie("TestCookie", "foobar"); 它会发送这样的头信息: Set-Cookie: TestCookie=foobar 如果未指定到期时间,cookie就会在浏览器关闭后被删除。
  • 23. HTTP Headers 中的 HTTP响应 WWW-Authenticate 一个网站可能会通过HTTP发送这个头部信息来验证用户。当浏览器看到头部有这个响应时就会打开一个弹出窗。 WWW-Authenticate: Basic realm="Restricted Area" 它会看起来像这样: Content-Encoding 这个头部通常会在返回内容被压缩时设置。 Content-Encoding: gzip
  • 24. 参考 http://css9.net/all-about-http-headers/ http://net.tutsplus.com/tutorials/other/http-headers-for-dummies/ http://www.w3.org/Protocols/rfc2616/rfc2616.html http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.3 http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.2