我在服务器端有一个Struts2动作用于文件下载.
<action name="download" class="com.xxx.DownAction">
<result name="success" type="stream">
<param name="contentType">text/plain</param>
<param name="inputName">imageStream</param>
<param name="contentDisposition">attachment;filename={fileName}</param>
<param name="bufferSize">1024</param>
</result>
</action>
Run Code Online (Sandbox Code Playgroud)
但是当我使用jQuery调用动作时:
$.post(
"/download.action",{
para1:value1,
para2:value2
....
},function(data){
console.info(data);
}
);
Run Code Online (Sandbox Code Playgroud)
在Firebug中我看到使用二进制流检索数据.我想知道如何打开用户可以在本地保存文件的文件下载窗口?
我有一个javascript应用程序,它将ajax POST请求发送到某个URL.响应可能是JSON字符串,也可能是文件(作为附件).我可以在我的ajax调用中轻松检测Content-Type和Content-Disposition,但是一旦我检测到响应包含文件,我该如何让客户端下载它?我在这里读过很多类似的帖子,但没有一个提供我正在寻找的答案.
请,请不要发布答案,建议我不应该使用ajax或者我应该重定向浏览器,因为这都不是一个选项.使用纯HTML表单也不是一种选择.我需要的是向客户端显示下载对话框.可以这样做,怎么做?
编辑:
显然,这不可能做到,但有一个简单的解决方法,如接受的答案所示.对于今后遇到这个问题的人来说,我的解决方法如下:
__PRE__
所以基本上,只需生成一个HTML表单,其中包含与AJAX请求中使用的相同的参数并提交它.
HTML5中实现的新功能之一是download锚标记的属性.此属性的好处是它为用户提供了下载在客户端应用程序中创建的内容的方法,例如图像(例如,从画布转换).
目前,对此功能的支持非常差,因此我想知道如何在浏览器中检测对此功能的支持.
我正在使用AngularJS,我正在尝试在php中生成PDF.这就是我在controller.js中的内容:
$scope.downloadPDF = function(){
$http.post('/download-pdf', { fid: $routeParams.fid })
.success(function(data, status, headers, config){
console.log("success");
})
.error(function(data, status, headers, config){
console.log("error");
});
};
Run Code Online (Sandbox Code Playgroud)
在我的php文件中,我有以下内容来创建带有FPDF库的PDF :
function download_pdf()
{
$id = $_POST['fid'];
$pdf = new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello World!');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename=' . $id . '.pdf');
$pdf->Output('Order123.pdf', 'D');
}
Run Code Online (Sandbox Code Playgroud)
但请求是响应此而不是打开保存对话框来保存我的pdf.
%PDF-1.3 3 0 obj <> endobj 4 0 obj <> streamx3Rðâ2Ð35W(çrQÐw3T04Ó30PISpêZ*[¤(hx¤æää+çå¤(j*dÔ7Wstndstreamendobj 1 0 obj <endobj 5 0 obj <endobj 2 0 obj <</ProcSet [/ PDF/Text/ImageB/ImageC/ImageI]/Font …
尝试在我的NodeJS服务器上创建文件下载功能时,我遇到了一些意外的行为.我有一个REST(快速)API,它需要一些导出数据功能,它在服务器上创建一个CSV文件并用于res.download('path/to/file')触发下载.响应头包括
Content-Disposition:attachment; filename="indicators.csv"
Content-Length:30125
Content-Type:text/csv; charset=UTF-8
Run Code Online (Sandbox Code Playgroud)
所以一切似乎都井然有序.
问题是,我从服务器得到的响应是纯文本.响应包含CSV文件包含的所有数据,但不会像我预期的那样触发浏览器的文件下载对话框.我在Chrome和FF上都试过了.两者都存在问题.
有任何想法吗?
更新
我设法通过创建一个虚拟表单,并使用其提交操作来进行我的AJAX调用来使其工作.但这是一个丑陋的黑客,我仍然在寻找一个更优雅的解决方案.
我正在尝试使用Ajax下载文件并显示自定义下载进度条.
问题是我无法理解如何这样做.我编写了代码来记录进度,但不知道如何启动下载.
注意:文件类型不同.
提前致谢.
JS
// Downloading of files
filelist.on('click', '.download_link', function(e){
e.preventDefault();
var id = $(this).data('id');
$(this).parent().addClass("download_start");
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
// Handle Download Progress
xhr.addEventListener("progress", function (evt) {
if(evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
}
}, false);
return xhr;
},
complete: function () {
console.log("Request finished");
}
})
});
Run Code Online (Sandbox Code Playgroud)
HTML和PHP
<li>
<div class="f_icon"><img src="' . $ico_path . '"></div>
<div class="left_wing">
<div class="progressbar"></div>
<a class="download_link" href="#" id="'.$file_id.'"><div class="f_name">' …Run Code Online (Sandbox Code Playgroud) 根据caniuse,在Microsoft Edge build 10547+中支持元素的download属性,但不支持IE或Safari.<a>
如何在不使用<a>带download属性集的元素或服务器的情况下下载文件对象?
尝试将简单文本字符串作为文件发送,根据请求以特定名称下载.似乎无法弄清楚为什么这段代码失败了.
var text_ready = "This is a content of a txt file."
res.setHeader('Content-type', "application/octet-stream");
res.setHeader('Content-disposition', 'attachment; filename=file.txt');
res.send( new Buffer(text_ready) );
Run Code Online (Sandbox Code Playgroud)
当此代码执行时,我只收到一个XHR响应(该字符串作为内容),但没有启动下载.但我希望收到此响应将强制浏览器下载一个文件,file.txt其名称包含上述字符串的内容.
如何解决?我究竟做错了什么?
也许这很重要:在Windows上的Chrome 41下工作.
编辑:似乎我必须更深入地描述.工作流程如下:
ng-click每个表格单元格都附有角度事件我正在使用以下脚本来启动文件下载:
if (file_exists($newfilename)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($newfilename));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($newfilename));
ob_clean();
flush();
readfile($newfilename);
exit;
}
Run Code Online (Sandbox Code Playgroud)
当我直接打开页面时,它工作正常,但问题是,我需要从另一个页面通过Ajax调用此脚本.当我这样做,然后下载没有开始.脚本的其余部分完成了它应该做的事情.
我认为问题是无法以这种方式使用头功能,但肯定有办法让这个工作吗?
如果它有任何帮助,这是Ajax函数:
<script type="text/javascript">
// function create GetXmlHttpObject
function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
if (window.ActiveXObject)
{
// code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
}
return null;
}
function submitVideoAjax(){
var myAjaxPostrequest=new GetXmlHttpObject();
var t2_title=document.video_form.title.value;
var parameters="title="+t2_title; …Run Code Online (Sandbox Code Playgroud) 我正在开发一个项目,我使用Django作为后端.我正在使用Django休息框架,我有一个API来下载文件.
@detail_route(methods=['GET'], permission_classes=[IsAuthenticated])
def test(self, request, pk=None):
try:
ticket = Ticket.objects.get(id=pk, user=request.user)
file_path = ticket.qrcode_file.path
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="image/jpeg")
name = "%s %s %s %s.jpg" % (ticket.show.title, datetime.strftime(ticket.show.date_time,
"%H_%M_%p"),
datetime.strftime(ticket.show.date_time, "%d %B %Y"), ticket.id)
response['Content-Disposition'] = "attachment; filename=%s" % name.replace(" ", "_")
return response
return Response({'error': 'Ticket doest not belong to requested user.'}, status=status.HTTP_403_FORBIDDEN)
except Ticket.DoesNotExist as e:
return Response({'error': str(e)}, status=status.HTTP_404_NOT_FOUND)
Run Code Online (Sandbox Code Playgroud)
在前端我使用Nuxtjs(ssr for vuejs).这是一小段代码,用户可以通过单击目标空白链接来下载文件:
<a class="downloadBtn" target="_blank" :href="`${baseURL}/payments/api/tickets/${ticket.id}/download_ticket/`">Download e-ticket</a>
Run Code Online (Sandbox Code Playgroud)
Web应用程序在Nuxtjs服务器(localhost:3000)上运行,Django服务器在localhost:8000上运行,只有API用于通过使用身份验证令牌在Nuxtjs和Django之间进行通信.
当我单击下载链接时,它会打开一个新选项卡并从该新选项卡发出请求,其中没有令牌与请求一起传递.因为,下载票的django视图是permission_classes=[IsAuthenticated] …