2013-03-11 142 views
2

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

这里是我的代码:

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; 

这是例子E分别请求:

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 

我检查Network标签在谷歌浏览萤火酷似工具栏和响应长相酷似文件。也许有什么毛病我的头,但我检查了已经经过两次......

PS 1

我想它使用AJAX来使(我宁愿它不是创建一个HTML表单更多)。

PS 2

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

+0

为什么不只是'...'? – 2013-03-11 15:05:12

回答

4

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

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

+0

原因是我在javascript层中有很多参数,我想用POST请求而不是GET来传递它们。假设你有10个参数要传递('param1','param2'等)到请求中。你将如何实现它不是为了写一个唯一的混乱(我的意思是难以理解的其他程序员)? – ducin 2013-03-11 15:10:44

+0

是的,正如你所看到的,'$'等等...... – ducin 2013-03-11 15:14:59

+0

对不起前面的问题 好的,这里是你需要的http://api.jquery.com/serialize/,这将为你做的代码 – 2013-03-11 15:15:45

2

你不使用AJAX下载文件。

你只需要给像<a href="myFile.jpeg">的URL,但问题是,你必须使用标头和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; 
} 

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

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> 
    

,并根据这是如何经常做的,你必须定期清理下载到不填服务器。