分享

了解HTTP Headers的方方面面(5)

 流曲频阳 2017-04-27

 


HTTP Headers 中的 HTTP响应


现在让我了解一些常见的HTTP Headers中的HTTP响应信息。


在PHP中,你可以通过 header() 来设置头部响应信息。PHP已经自动发送了一些必要的头部信息,如 载入的内容,设置 cookies 等等… 你可以通过 headers_list() 函数看到已发送和将要发送的头部信息。你也可以使用headers_sent()函数来检查头部信息是否已经被发送。


Cache-Control


的定义是:“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


更多详情请参见


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列表。


在PHP中你可以通过 finfo_file() 来检测文件的ime-type。


Content-Disposition


这个头部信息将告诉浏览器打开一个文件下载窗口,而不是试图解析该响应的内容。例如:


Content-Disposition: attachment; filename="download.zip"


他会导致浏览器出现这样的对话框:



注意,适合它的Content-Type头信息同时也会被发送


Content-Type: application/zip

Content-Disposition: attachment; filename="download.zip"


Content-Length


当内容将要被传输到浏览器时,服务器可以通过该头部告知浏览器将要传送文件的大小(bytes)。


Content-Length: 89123


对于文件下载来说这个信息相当的有用。这就是为什么浏览器知道下载进度的原因。


例如,这里我写了一段虚拟脚本,来模拟一个慢速下载。


// it's a zip file

header('Content-Type: application/zip');

// 1 million bytes (about 1megabyte)

header('Content-Length: 1000000');

// load a download dialogue, and save it as download.zip

header('Content-Disposition: attachment; filename="download.zip"');

// 1000 times 1000 bytes of data

for ($i = 0; $i < 1000; $i++) {

echo str_repeat(".",1000);

// sleep to slow down the download

usleep(50000);

}


结果将会是这样的:



现在,我将Content-Length头部注释掉:


// it's a zip file

header('Content-Type: application/zip');

// the browser won't know the size

// header('Content-Length: 1000000');

// load a download dialogue, and save it as download.zip

header('Content-Disposition: attachment; filename="download.zip"');

// 1000 times 1000 bytes of data

for ($i = 0; $i < 1000; $i++) {

echo str_repeat(".",1000);

// sleep to slow down the download

usleep(50000);

}


结果就变成了这样:



这个浏览器只会告诉你已下载了多少,但不会告诉你总共需要下载多少。而且进度条也不会显示进度。


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


$modify_time = filemtime($file);

header("Last-Modified: " . gmdate("D, d M Y H:i:s", $modify_time) . " GMT");


它提供了另一种缓存机制。浏览器可能会发送这样的请求:


If-Modified-Since: Sat, 28 Nov 2009 06:38:19 GMT


在If-Modified-Since一节我们已经讨论过了。


Location


这个头部是用来重定向的。如果响应代码为 301 或者 302 ,服务器就必须发送该头部。例如,当你访问 http://www. 时浏览器就会收到如下的响应:


HTTP/1.x 301 Moved Permanently

...

Location: http://net./

...


在PHP中你可以通过这种方式对访客重定向:

header('Location: http://net./');


默认会发送302状态码,如果你想发送301,就这样写:


header('Location: http://net./', true, 301);


Set-Cookie


当一个网站需要设置或者更新你浏览的cookie信息时,它就会使用这样的头部:


Set-Cookie: skin=noskin; path=/; domain=.amazon.com; expires=Sun, 29-Nov-2009 21:42:28 GMT

Set-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就会在浏览器关闭后被删除。


WWW-Authenticate


一个网站可能会通过HTTP发送这个头部信息来验证用户。当浏览器看到头部有这个响应时就会打开一个弹出窗。


WWW-Authenticate: Basic realm="Restricted Area"


它会看起来像这样:



PHP手册的一章中就有一段简单的代码演示了如果用PHP做这样的事情:


if (!isset($_SERVER['PHP_AUTH_USER'])) {

header('WWW-Authenticate: Basic realm="My Realm"');

header('HTTP/1.0 401 Unauthorized');

echo 'Text to send if user hits Cancel button';

exit;

} else {

echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";

echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";

}


Content-Encoding


这个头部通常会在返回内容被压缩时设置。


Content-Encoding: gzip


在PHP中,如果你调用了ob_gzhandler()函数,这个头部将会自动被设置。


中文译文HTTP Headers 入门 | 感谢robin的辛勤劳动

英文原文HTTP Headers for Dummies


PS: 这是本站第一篇转载的文章,以后如果遇到国内的优秀文章、作品,也会通过转载的方式呈现给大家,不再拘泥于原创及翻译。如果大家有好的文章也可向我推荐。







               

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多