【问题标题】:Download file with AJAX call使用 AJAX 调用下载文件
【发布时间】:2012-07-27 09:04:35
【问题描述】:

我正在尝试将一些详细信息附加到文件中并添加以供下载。

我为此使用 JavaScript 和 PHP。点击下载按钮,它将触发 AJAX 请求。

$.ajax({
  url:"php/test.php",
  type: 'POST',
  data: { totalQuery : test1, },

  success: function(finalEntityList){
  },
});

假设test.php 有一个单行代码

$html="Test";

现在我想将它添加到一个文件中并使其可供下载。我已经使用了代码

header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=data.csv');
$output = fopen('php://output', 'w');
fwrite($output, $html);
fclose($output);

但是下载不会自动开始...我必须使用 firebug 打开 POST 请求链接,以便启动下载..可能是什么问题??

【问题讨论】:

  • 把你的文件名放在引号header('Content-Disposition: attachment; filename="data.csv"');
  • @jav - 如果您要编辑帖子 - 尝试修复 所有 问题 - not just one or two mistakes。

标签: php javascript ajax download


【解决方案1】:

也许您需要做的只是通过 AJAX 调用返回文件的路径,然后使用 JavaScript 通过以下方式之一“启动”下载 -

  • window.open
  • window.location.href
$.ajax({
  url:"php/test.php",
  type: 'POST',
  dataType: 'json',
  data: { totalQuery : test1, },

  success: function(response){
    // initiate download using direct path to file
    window.location.href = response.URL;
  }
});

现在您的test.php 文件只需要以 JSON 格式返回下载文件的 URL 路径 -

$filename = 'data.csv';
$path = $_SERVER['DOCUMENT_ROOT'].'/downloads/';
echo json_encode(array('URL'=>$path.$filename));

您可能会考虑将 URL 作为原始字符串返回 - 但我觉得使用 JSON 可能会更好,因为您可以轻松地将其他信息添加到响应中,而无需额外的解析函数。所有这一切使它成为一个更可靠的选择。

【讨论】:

  • 我不确定,使用 php 进行文件下载时的默认路径可能是什么
  • 路径只是代表文件的 URL。如果该文件位于您的 Web 根文件夹中,那么它就是您的站点名称和文件名 - http://yourdomain.com/data.csv
  • 路径是脚本所在的位置,所以如果脚本在http://yourdomain.com/script/download.php,那么该脚本的文件根目录就是http://yourdomain.com/script/
【解决方案2】:

它需要更多的参数和headerinfo:

$file = "data.csv";
$mime_type = "text/csv";
$size = filesize($file);
$name = rawurldecode($name);

@ob_end_clean(); //turn off output buffering to decrease cpu usage

// required for IE, otherwise Content-Disposition may be ignored
if(ini_get('zlib.output_compression'))
    ini_set('zlib.output_compression', 'Off');

header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');

/* The three lines below basically make the
download non-cacheable */
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, $range_end) = explode("-", $range);
    $range=intval($range);
    if(!$range_end)
    {
        $range_end=$size-1;
    } 
    else
    {
        $range_end=intval($range_end);
    }

    $new_length = $range_end-$range+1;
    header("HTTP/1.1 206 Partial Content");
    header("Content-Length: $new_length");
    header("Content-Range: bytes $range-$range_end/$size");
} 
else
{
    $new_length=$size;
    header("Content-Length: ".$size);
}

/* output the file itself */
$chunksize = 1*(1024*1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($file, 'r'))
{
    if(isset($_SERVER['HTTP_RANGE']))
        fseek($file, $range);

    while(!feof($file) && (!connection_aborted()) && ($bytes_send<$new_length))
    {
        $buffer = fread($file, $chunksize);
        print($buffer); //echo($buffer); // is also possible
        flush();
        $bytes_send += strlen($buffer);
    }
    fclose($file);
} 
else 
    die('Error - can not open file.');

【讨论】:

  • JavaScript 方面呢?这看起来会启动文件下载 - 但是当由 jQuery AJAX 调用启动时它会如何表现?
  • 您可以将 $file 变量设置为 POST 变量:$file = $_POST['file']; 然后制作一个表单以 POST 到 PHPscript(最好使用 target="_blank" 打开一个新的选项卡/窗口,文件将在其中下载。在 Chrome 和 FF 中,选项卡将自动关闭并启动下载。在 IE 中,将打开一个新窗口,并询问用户如何处理文件(打开/保存/取消))
猜你喜欢
  • 2023-04-01
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
  • 2014-05-27
  • 2011-11-26
  • 2015-06-01
  • 2014-04-27
  • 2011-10-03
相关资源
最近更新 更多