HTTP头文件下载 [英] HTTP Headers for File Downloads
问题描述
我现在有一些问题,有些用户报告某些文件被错误地标识(所以无论扩展名是什么,浏览器会将其视为GIF图像)。我猜这是因为我没有在响应头中设置Content-type。这很可能是这样吗?如果是这样,是否有一个相当通用的类型,可以用于所有文件,而不是试图解释每一个可能的文件类型?
目前我只设置值Content-disposition:attachment; filename = arandomf.ile
更新:我遵循本指南来构建一个更健壮的过程档案下载( http:/ /w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/ ),但脚本执行时间和浏览器的下载对话框出现。谁能识别造成这种情况的瓶颈?
这是我的实现:
/ **
*将指定的文件输出到浏览器。
*
* @param string $ filePath输出文件的路径
* @param string $ fileName文件的名称
* @param string $ mimeType的类型文件
* /
函数outputFile($ filePath,$ fileName,$ mimeType =''){
//设置
$ mimeTypes =数组(
'pdf' ='application / pdf',
'txt'=>'text / plain',
'html'=>'text / html',
'exe'=> ;'application / octet-stream',
'zip'=>'application / zip',
'doc'=>'application / msword',
'xls'=> ;'application / vnd.ms-excel',
'ppt'=>'application / vnd.ms-powerpoint',
'gif'=>'image / gif',
'png'=>'image / png',
'jpeg'=>'image / jpg',
'jpg'=>'image / jpg' php'=>'text / plain'
);
$ fileSize = filesize($ filePath);
$ fileName = rawurldecode($ fileName);
$ fileExt ='';
//确定MIME类型
if($ mimeType ==''){
$ fileExt = strtolower(substr(strrchr($ filePath,'。'),1) );
if(array_key_exists($ fileExt,$ mimeTypes)){
$ mimeType = $ mimeTypes [$ fileExt];
}
else {
$ mimeType ='application / force-download';
}
}
//禁用输出缓冲
@ob_end_clean();
// IE必需
if(ini_get('zlib.output_compression')){
ini_set('zlib.output_compression','Off');
}
//发送标题
header('Content-Type:'。$ mimeType);
header('Content-Disposition:attachment; filename ='。$ fileName。'');
header('Content-Transfer-Encoding:binary');
header('Accept-Ranges:bytes');
//发送头文件:阻止文件缓存
头('Cache-Control:private');
header('Pragma:private');
header('Expires:Mon,26 Jul 1997 05:00:00 GMT');
//多部分 - 下载和下载恢复支持
if(isset($ _ SERVER ['HTTP_RANGE'])){
list($ a,$ range)= explode '=',$ _SERVER ['HTTP_RANGE'],2);
list($ range)= explode(',',$ range,2);
list($ range,$ rangeEnd)= explode(' - ',$ range);
$ range = intval($ range);
if(!$ rangeEnd){
$ rangeEnd = $ fileSize - 1;
}
else {
$ rangeEnd = intval($ rangeEnd);
}
$ newLength = $ rangeEnd - $ range + 1;
//发送头
头('HTTP / 1.1 206部分内容');
header('Content-Length:'。$ newLength);
header('Content-Range:bytes'。$ range - $ rangeEnd / $ size);
}
else {
$ newLength = $ size;
header('Content-Length:'。$ size);
}
//输出文件
$ chunkSize = 1 *(1024 * 1024);
$ bytesSend = 0;
if($ file = fopen($ filePath,'r')){
if(isset($ _ SERVER ['HTTP_RANGE'])){
fseek($ file ,$ range);
while(!feof($ file)&!connection_aborted()& $ bytesSend< $ newLength){
$ buffer = fread($ file,$ chunkSize );
echo $ buffer;
flush();
$ bytesSend + = strlen($ buffer);
}
fclose($ file);
}
}
}
实现的建议操作接收到一个
application / octet-stream实体是
只是提供将数据放在
a文件中
所以我会去那个。 p>
I've written a PHP script that handles file downloads, determining which file is being requested and setting the proper HTTP headers to trigger the browser to actually download the file (rather than displaying it in the browser).
I now have a problem where some users have reported certain files being identified incorrectly (so regardless of extension, the browser will consider it a GIF image). I'm guessing this is because I haven't set the "Content-type" in the response header. Is this most likely the case? If so, is there a fairly generic type that could be used for all files, rather than trying to account for every possible file type?
Currently I'm only setting the value "Content-disposition: attachment; filename=arandomf.ile"
Update: I followed this guide here to build a more robust process for file downloads (http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/), but there is a significant delay between when the script is executed and when the browser's download dialog appears. Can anyone identify the bottleneck that is causing this?
Here's my implementation:
/**
* Outputs the specified file to the browser.
*
* @param string $filePath the path to the file to output
* @param string $fileName the name of the file
* @param string $mimeType the type of file
*/
function outputFile($filePath, $fileName, $mimeType = '') {
// Setup
$mimeTypes = array(
'pdf' => 'application/pdf',
'txt' => 'text/plain',
'html' => 'text/html',
'exe' => 'application/octet-stream',
'zip' => 'application/zip',
'doc' => 'application/msword',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
'gif' => 'image/gif',
'png' => 'image/png',
'jpeg' => 'image/jpg',
'jpg' => 'image/jpg',
'php' => 'text/plain'
);
$fileSize = filesize($filePath);
$fileName = rawurldecode($fileName);
$fileExt = '';
// Determine MIME Type
if($mimeType == '') {
$fileExt = strtolower(substr(strrchr($filePath, '.'), 1));
if(array_key_exists($fileExt, $mimeTypes)) {
$mimeType = $mimeTypes[$fileExt];
}
else {
$mimeType = 'application/force-download';
}
}
// Disable Output Buffering
@ob_end_clean();
// IE Required
if(ini_get('zlib.output_compression')) {
ini_set('zlib.output_compression', 'Off');
}
// Send Headers
header('Content-Type: ' . $mimeType);
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
// Send Headers: Prevent Caching of File
header('Cache-Control: private');
header('Pragma: private');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
// Multipart-Download and Download Resuming Support
if(isset($_SERVER['HTTP_RANGE'])) {
list($a, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
list($range) = explode(',', $range, 2);
list($range, $rangeEnd) = explode('-', $range);
$range = intval($range);
if(!$rangeEnd) {
$rangeEnd = $fileSize - 1;
}
else {
$rangeEnd = intval($rangeEnd);
}
$newLength = $rangeEnd - $range + 1;
// Send Headers
header('HTTP/1.1 206 Partial Content');
header('Content-Length: ' . $newLength);
header('Content-Range: bytes ' . $range - $rangeEnd / $size);
}
else {
$newLength = $size;
header('Content-Length: ' . $size);
}
// Output File
$chunkSize = 1 * (1024*1024);
$bytesSend = 0;
if($file = fopen($filePath, 'r')) {
if(isset($_SERVER['HTTP_RANGE'])) {
fseek($file, $range);
while(!feof($file) && !connection_aborted() && $bytesSend < $newLength) {
$buffer = fread($file, $chunkSize);
echo $buffer;
flush();
$bytesSend += strlen($buffer);
}
fclose($file);
}
}
}
Acoording to RFC 2046 (Multipurpose Internet Mail Extensions):
The recommended action for an implementation that receives an
"application/octet-stream" entity is to simply offer to put the data in a file
So I'd go for that one.
这篇关于HTTP头文件下载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!