通过Ajax和PHP强制下载

时间:2022-12-28 09:49:10

i want to create a downloadscript which allows Force Download of JPGs. This is my php script:

我想创建一个下载脚本,允许强制下载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']);
?>

This is a code segment of my js code:

这是我的js代码的代码段:

function downloadFile(a){
    document.location = "download.php?a="+ a;
}

With this code sample nothing happens. If i append the result into a HTML-tag, it shows the content of the file.

使用此代码示例没有任何反应。如果我将结果附加到HTML标记中,它会显示文件的内容。

Any ideas how to teach the browser to download this file?

任何想法如何教浏览器下载此文件?

EDIT: SCRIPT UPDATE

编辑:脚本更新

5 个解决方案

#1


18  

You can't download files with ajax. So, if you have something that should happen on ajax, you should return url in response and apply it like document.location = "url"to start download process.

您无法使用ajax下载文件。所以,如果你有一些应该在ajax上发生的事情,你应该返回url作为响应并应用它像document.location =“url”来开始下载过程。

One note here. As I remember, browser will block file download if it is initiated not by user click. So, this will work fine:

这里有一点说明。我记得,如果不是通过用户点击启动浏览器,它将阻止文件下载。所以,这将工作正常:

.click(function(){
   document.location = "download url"
})

But if it is started not by user click, it will be blocked. So, code like this:

但如果它不是由用户点击启动,它将被阻止。所以,这样的代码:

.click(function(){
       $.ajax({...,
       success:function(download_url_from_server){
           document.location = download_url_from_server;
       }});           
    })

will be blocked by browser. So, if you want to pass some data with a post, you may submit a form into hidden iframe or to blank page using <form target="...":

将被浏览器阻止。因此,如果您想通过帖子传递一些数据,您可以使用

 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();
}

And in script.php you need to execute code from download.php immediately, if token is Ok, or do a redirect to download script:

在script.php中,如果令牌为Ok,则需要立即执行download.php中的代码,或者重定向下载脚本:

header("Location: download.php?a=" . $filename)

#2


3  

Setting the mime type to image/jpeg will most probably not work. So, you need application/octet-stream instead to force the download.

将mime类型设置为image / jpeg很可能不起作用。因此,您需要application / octet-stream来强制下载。

Replace the content type header in your php with the following:

用以下内容替换php中的内容类型标题:

header('Content-Type: application/octet-stream'); 

Also, One nice solution instead of using document.location is to inject an iframe. Use the following function in your success callback

此外,一个不错的解决方案,而不是使用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;   
    }

#3


1  

It seems you have errors in your script. First of all, correct speliing for GET variable is $_GET['a'], not $GET['a']. The second issue here is that you have extra opening parenthesis, when I copied your code, I received 500 Internal Server Error response. If we correct mistakes, it seems to work fine. Just try corrected version of your code.

您的脚本中似乎有错误。首先,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']);
?>

#4


0  

You're getting it confused a bit. As FAngel pointed out, you can't download files via AJAX. What you need to do is redirect the user to another page that then has your above PHP code in it. That PHP code should then allow the user to download the file directly. What you're attempting is absolutely possible, you just need to approach it from another direction, ie not with AJAX.

你有点困惑。正如FAngel指出的那样,你无法通过AJAX下载文件。您需要做的是将用户重定向到另一个页面,然后在其中包含您的上述PHP代码。那么PHP代码应该允许用户直接下载文件。你正在尝试的是绝对可能的,你只需要从另一个方向接近它,即不是用AJAX。

#5


0  

You can force download file with Mouse middle event:

您可以使用鼠标中间事件强制下载文件:

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);

#1


18  

You can't download files with ajax. So, if you have something that should happen on ajax, you should return url in response and apply it like document.location = "url"to start download process.

您无法使用ajax下载文件。所以,如果你有一些应该在ajax上发生的事情,你应该返回url作为响应并应用它像document.location =“url”来开始下载过程。

One note here. As I remember, browser will block file download if it is initiated not by user click. So, this will work fine:

这里有一点说明。我记得,如果不是通过用户点击启动浏览器,它将阻止文件下载。所以,这将工作正常:

.click(function(){
   document.location = "download url"
})

But if it is started not by user click, it will be blocked. So, code like this:

但如果它不是由用户点击启动,它将被阻止。所以,这样的代码:

.click(function(){
       $.ajax({...,
       success:function(download_url_from_server){
           document.location = download_url_from_server;
       }});           
    })

will be blocked by browser. So, if you want to pass some data with a post, you may submit a form into hidden iframe or to blank page using <form target="...":

将被浏览器阻止。因此,如果您想通过帖子传递一些数据,您可以使用

 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();
}

And in script.php you need to execute code from download.php immediately, if token is Ok, or do a redirect to download script:

在script.php中,如果令牌为Ok,则需要立即执行download.php中的代码,或者重定向下载脚本:

header("Location: download.php?a=" . $filename)

#2


3  

Setting the mime type to image/jpeg will most probably not work. So, you need application/octet-stream instead to force the download.

将mime类型设置为image / jpeg很可能不起作用。因此,您需要application / octet-stream来强制下载。

Replace the content type header in your php with the following:

用以下内容替换php中的内容类型标题:

header('Content-Type: application/octet-stream'); 

Also, One nice solution instead of using document.location is to inject an iframe. Use the following function in your success callback

此外,一个不错的解决方案,而不是使用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;   
    }

#3


1  

It seems you have errors in your script. First of all, correct speliing for GET variable is $_GET['a'], not $GET['a']. The second issue here is that you have extra opening parenthesis, when I copied your code, I received 500 Internal Server Error response. If we correct mistakes, it seems to work fine. Just try corrected version of your code.

您的脚本中似乎有错误。首先,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']);
?>

#4


0  

You're getting it confused a bit. As FAngel pointed out, you can't download files via AJAX. What you need to do is redirect the user to another page that then has your above PHP code in it. That PHP code should then allow the user to download the file directly. What you're attempting is absolutely possible, you just need to approach it from another direction, ie not with AJAX.

你有点困惑。正如FAngel指出的那样,你无法通过AJAX下载文件。您需要做的是将用户重定向到另一个页面,然后在其中包含您的上述PHP代码。那么PHP代码应该允许用户直接下载文件。你正在尝试的是绝对可能的,你只需要从另一个方向接近它,即不是用AJAX。

#5


0  

You can force download file with Mouse middle event:

您可以使用鼠标中间事件强制下载文件:

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);

相关文章