我想创建一个允许强制下载JPG的下载文件。 这是我的PHP脚本:
<?php
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Description: File Transfer");
header("Content-Type: image/jpg");
header('Content-Disposition: attachment; filename="'.basename($GET['a']).'"');
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize(($GET['a']));
readfile(($GET['a']);
?>
这是我的js代码的代码段:
function downloadFile(a){
document.location = "download.php?a="+ a;
}
使用此代码示例没有任何反应。如果我将结果附加到HTML标记中,它会显示文件的内容。
如何教导浏览器下载此文件的任何想法?
编辑:脚本更新
答案 0 :(得分:19)
您无法使用ajax下载文件。因此,如果你在ajax上发生了某些事情,你应该回复url并像document.location = "url"
一样应用它来开始下载过程。
这里有一点注意。我记得,如果不是通过用户点击启动浏览器,它将阻止文件下载。所以,这样可以正常工作:
.click(function(){
document.location = "download url"
})
但如果不是通过用户点击启动它,它将被阻止。所以,像这样的代码:
.click(function(){
$.ajax({...,
success:function(download_url_from_server){
document.location = download_url_from_server;
}});
})
将被浏览器阻止。因此,如果您想通过帖子传递一些数据,可以使用<form target="..."
将表单提交到隐藏的iframe或空白页:
function checkToken(token){
var $form = $("#downloadForm");
if ($form.length == 0) {
$form = $("<form>").attr({ "target": "_blank", "id": "downloadForm", "method": "POST", "action": "script.php" }).hide();
$("body").append($form);
}
$form.find("input").remove();
var args = { a: "checkToken", b: token }
for (var field in args) {
$form.append($("<input>").attr({"value":args[field], "name":field}));
}
$form.submit();
}
在script.php中,你需要立即执行download.php中的代码,如果令牌是Ok,或者重定向下载脚本:
header("Location: download.php?a=" . $filename)
答案 1 :(得分:3)
将mime类型设置为image/jpeg
很可能无法正常工作。因此,您需要application/octet-stream
来强行下载。
使用以下内容替换php中的内容类型标题:
header('Content-Type: application/octet-stream');
此外,一个不错的解决方案,而不是使用document.location
是注入一个iframe。在成功回调中使用以下功能
function downloadFile(url)
{
var iframe;
iframe = document.getElementById("download-container");
if (iframe === null)
{
iframe = document.createElement('iframe');
iframe.id = "download-container";
iframe.style.visibility = 'hidden';
document.body.appendChild(iframe);
}
iframe.src = url;
}
答案 2 :(得分:1)
您的脚本中似乎有错误。 首先,GET变量的正确拼写是$ _GET ['a'],而不是$ GET ['a']。 这里的第二个问题是你有额外的左括号,当我复制你的代码时,我收到500内部服务器错误响应。 如果我们纠正错误,它似乎工作正常。 只需尝试修正您的代码版本。
<?php
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Description: File Transfer");
header("Content-Type: image/jpg");
header('Content-Disposition: attachment; filename="'.basename($_GET['a']).'"');
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($_GET['a']));
readfile($_GET['a']);
?>
答案 3 :(得分:0)
你有点困惑。正如FAngel指出的那样,你无法通过AJAX下载文件。您需要做的是将用户重定向到另一个页面,然后在其中包含您的上述PHP代码。那么PHP代码应该允许用户直接下载文件。你正在尝试的是绝对可能的,你只需要从另一个方向接近它,即不是用AJAX。
答案 4 :(得分:0)
您可以使用鼠标中间事件强制下载文件:
const url = "https://www.google.com.vn/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png";
const forceDownload = url => {
try {
const link = document.createElement('a');
const fileName = url.substring(url.lastIndexOf('/') + 1, url.length);
const event = new MouseEvent( "click", { "button": 1, "which": 1 });
link.href = url;
link.download = fileName;
link.dispatchEvent(event);
} catch(e) {
document.location = url;
}
}
forceDownload(url);