通过AJAX POST下载文件

时间:2013-03-11 15:01:12

标签: php ajax post symfony download

我正在尝试使用AJAX POST请求提供简单的下载。用户单击<span>并开始下载(或显示下载对话框,具体取决于浏览器)。我实现了所有这些,但AJAX响应不会触发任何浏览器下载行为,我不知道为什么。

这是我的代码:

HTML /树枝:

<span id="export_csv">csv - click me to download the file</span>

的javascript:

<script type="text/javascript">
$(document).ready(function() {
  $('#export_csv').click(function(){
    var params = "some params";
    $.ajax({
      type: 'POST',
      url:  "{{path('ExportBundle_export', {'format': 'csv','report' : 'basic'})}}",
      data: params
    });
  });
});
</script>

控制器代码(symfony2,但这里没关系):

$response = new Response(file_get_contents($document->getPath()));
$response->setStatusCode(200);
$response->headers->set('Content-Type', $document->getMime());
$response->headers->set('Content-Description', 'Submissions Export');
$response->headers->set('Content-Disposition', 'attachment; filename='
    . $filename . '.' . $format);
$response->headers->set('Content-Transfer-Encoding', 'binary');
$response->headers->set('Pragma', 'no-cache');
$response->headers->set('Expires', '0');
return $response;

这是示例请求:

Request URL:http://myapp.local/app_dev.php/export/basic/csv
Request Method:POST
Status Code:200 OK

和响应标题:

cache-control:private, must-revalidate
Connection:close
content-description:Submissions Export
content-disposition:attachment; filename=report_1363013244.csv
Content-Length:790
content-transfer-encoding:binary
Content-Type:text/csv; charset=UTF-8
Date:Mon, 11 Mar 2013 14:47:24 GMT
expires:0
pragma:no-cache
Server:Apache/2.2.22 (Ubuntu)
x-debug-token:513dee7c99fdb
X-Powered-By:PHP/5.3.10-1ubuntu3.5

我已经检查了Google Chrome firebug相似工具栏中的Network标签,其响应与文件完全相同。也许我的标题有问题,但我已经检查了两次......

PS 1

我想使用AJAX(我更喜欢创建HTML表单)。

PS 2

我在客户端层(javascript)中有很多参数。我需要所有这些都在控制器(服务器端脚本)中可用。使用AJAX时,我只需在data键中传递它们。

3 个答案:

答案 0 :(得分:4)

我不明白你为什么要触发下载的ajax调用? 为什么不直接进行常规<a href="download/me">Download</a>并设置该页面的mime类型。这样你就可以运行任何php代码,然后回显一个mime类型,这不会导致页面重新加载,你将留在你点击的页面。

http://davidwalsh.name/php-header-mime

答案 1 :(得分:2)

您不使用AJAX下载文件。

您只需提供类似<a href="myFile.jpeg">的网址,但问题是您必须使用标头强制下载并URL Rewriting拦截请求:

如果是图片:


$filename = basename($_GET['img']); // don't accept other directories
$size = @getimagesize($filename);
$fp = @fopen($filename, "rb");
if ($size && $fp)
{
   header("Content-type: {$size['mime']}");
   header("Content-Length: " . filesize($filename));
   header("Content-Disposition: attachment; filename=$filename");
   header('Content-Transfer-Encoding: binary');
   header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
   fpassthru($fp);
   exit;
}

在这种情况下..网址不会被更改(我认为这就是你想要的)

答案 2 :(得分:0)

我不认为它可能使用ajax,我遇到了同样的问题并且没有触发下载。我的解决方案只使用PHP:

  1. 在后台加载页面时创建新文件。这将存储在服务器位置。

    $out = fopen('filename', 'w+');
    //write data in file
    fputcsv($out, some csv values );
    
  2. 有一个指向客户端的链接以便下载

    <a href='<?php echo $filename;?>' >Export Data to CSV file</a>
    
  3. 根据此操作的频率,您必须定期清理下载内容,以免填满服务器。