常用http头

404
header('HTTP/1.1 404 Not Found');

301,302
#firefox中有时会缓存301跳转所以加上了缓存过期
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")."GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Pragma: no-cache");
header('HTTP/1.1 301 Moved Permanently');
header('Location: '.$url,true,301);

附件下载
header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
header("Content-Description: File Transfer");
header ("Content-type: application/octet-stream");
header ("Content-Length: " .filesize ($f_name));
header ("Content-Disposition: attachment; filename=" . basename($f_name));
readfile($f_name);

PHPExcel下载
$filename='联盟排行榜'.$date.'.xlsx';
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header('Content-Disposition:inline;filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
$objWriter->save('php://output');

Excel
header('Content-Type: application/vnd.ms-excel');
header("Content-Disposition:attachment; filename=demo.xls");
header('Cache-Control: max-age=0');
//定义编码
header( 'Content-Type:text/html;charset=utf-8 ');

//Atom
header('Content-type: application/atom+xml');

//CSS
header('Content-type: text/css');

//Javascript
header('Content-type: text/javascript');

//JPEG Image
header('Content-type: image/jpeg');

//JSON
header('Content-type: application/json');

//PDF
header('Content-type: application/pdf');

//RSS
header('Content-Type: application/rss+xml; charset=ISO-8859-1');

//Text (Plain)
header('Content-type: text/plain');

//XML
header('Content-type: text/xml');

// ok
header('HTTP/1.1 200 OK');

//设置一个404头:
header('HTTP/1.1 404 Not Found');

//设置地址被永久的重定向
header('HTTP/1.1 301 Moved Permanently');

//转到一个新地址
header('Location: http://www.example.org/');

//文件延迟转向:
header('Refresh: 10; url=http://www.example.org/');
print 'You will be redirected in 10 seconds';

//当然,也可以使用html语法实现
// <meta http-equiv="refresh" content="10;http://www.example.org/ />

// override X-Powered-By: PHP:
header('X-Powered-By: PHP/4.4.0');
header('X-Powered-By: Brain/0.6b');

//文档语言
header('Content-language: en');

//告诉浏览器最后一次修改时间
$time = time() - 60; // or filemtime($fn), etc
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT');

//告诉浏览器文档内容没有发生改变
header('HTTP/1.1 304 Not Modified');

//设置内容长度
header('Content-Length: 1234');

//设置为一个下载类型
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="example.zip"');
header('Content-Transfer-Encoding: binary');
// load the file to send:
readfile('example.zip');

// 对当前文档禁用缓存
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Pragma: no-cache');

//设置内容类型:
header('Content-Type: text/html; charset=iso-8859-1');
header('Content-Type: text/html; charset=utf-8');
header('Content-Type: text/plain'); //纯文本格式
header('Content-Type: image/jpeg'); //JPG***
header('Content-Type: application/zip'); // ZIP文件
header('Content-Type: application/pdf'); // PDF文件
header('Content-Type: audio/mpeg'); // 音频文件
header('Content-Type: application/x-shockw**e-flash'); //Flash动画

//显示登陆对话框
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Top Secret"');
print 'Text that will be displayed if the user hits cancel or ';
print 'enters wrong login data';

 

通过http头设置http缓存

通过nginx可以设置http缓存

location ~* \.(js|css|gif|jpeg|jpg|png|ico|bmp)$ {
 expires 7d;
 access_log off;
 break;
}

用Chrome浏览器测试确实有缓存了,但是F5刷新接收到304之后还是会下载内容(和Ctrl+F5不同,Ctrl+F5会强制清除缓存并获取新内容,因为F5会发送If-Modified-Since和Ctrl+F5不会发送),用火狐浏览器测试接收到304之后并不下载实际文件内容(firebug时间线里面接收数据的部分所用时间是零),看样是浏览器之间的差异了。另外这样配置nginx的话在Chrome中图片缓存还是有问题,就下面这个截图我重新上传了之后(图片url和之前的图片一样)只有通过Ctrl+F5才会更新,Chrome对待js和img的方式不同。

通过PHP产生的JS也可以缓存

$content="var url={ base:'{$url['base']}',css:'{$url['css']}',js:'{$url['js']}',img:'{$url['img']}',image:'{$url['image']}',current:window.location};";
$expire=604800;
header('Content-type: application/x-javascript');
header('Cache-Control: max-age='.$expire);//1 month
//$now=gmmktime();
//header('Last-Modified: '.gmdate('D, d M Y H:i:s',$now-$expire).' GMT');
//header('Expires: '.gmdate('D, d M Y H:i:s', $now+$expire).' GMT');
header('Accept-Ranges: bytes');
header('Content-Length: '.strlen($content));
echo $content;

Accept-Ranges 和 Content-Length 也需要加上,头信息中如果不存在Content-Length 服务器端就会发送Tansfer-Encoding:chunked ,这个头信息的的意思是response的内容会被分成一块一块的发送,客户端不会等到内容都传输完毕了才解析其中的内容。如果指定了Content-Length 客户端会在接受完Content-Length长度的数据之后开始解析,这样就可以被缓存。

RFC上说Last-Modified和Expires 在这里被Cache-Control覆盖掉了,因为没仔细研究HTTP协议所以先放这。具体见撰写本文时的最新RFC2616直接搜索 Page 126 就看到了。