【问题标题】:jQuery.ajax, PHP, HTTP Hyperlink download not workingjQuery.ajax、PHP、HTTP 超链接下载不起作用
【发布时间】:2013-06-05 19:08:14
【问题描述】:

我想实现一个简单的计数器来跟踪文件下载了多少次。我们在这里讨论的是大文件,所以我无法使用 readfile()、fpassthru() 或类似的方法将整个文件加载到 php 的内存中。

另外,对于这个解决方案,我想使用直接链接,然后通过 jQuery.ajax 更新计数器。我之所以选择这种方式,是因为带有 X-Sendfile 的 download.php 对我来说不起作用 - 通常我会收到多次调用脚本以进行一次下载,这完全打乱了我的计数。 (这可能是由于 Chrome 对 favicon 的额外请求,但我不确定。另外,这不是问题。)

这基本上是我的 index.html:

<a href="downloads/bla.zip"><span class="countDownload">bla</span></a>

这是 jQuery:

$(document).ready(function() {

    $("body").on("click", ".countDownload", function() {
        var filename = $(this).parent().attr("href");
        filename = filename.split("/");
        filename = filename[filename.length - 1]

        var request = $.ajax({
            url: "counter.php?file=" + filename
        });

        request.done(function(msg) {
            alert("yes");
        });

        request.fail(function(jqXHR, textStatus) {
            alert("no");
        });

        // if this is here, ajax works, but download fails
        return false;


    });
});

如果"return false;"在那里,ajax请求会成功,但是文件下载会被抑制。 如果“返回false;”不存在,ajax 请求将失败(“取消”),但反过来文件下载工作正常。

感谢任何帮助!

【问题讨论】:

  • 触发ajax的类基本上没有理由在;我认为它也可能在 中。
  • 尝试将其放入&lt;a&gt; 看看会发生什么
  • 不会改变任何事情。

标签: php jquery ajax download counter


【解决方案1】:

100% 未经测试,但只是一个想法......

$(document).ready(function() {

$("body").on("click", ".countDownload", function(e) {
    e.preventDefault();

    var filename = $(this).parent().attr("href");
    filename = filename.split("/");
    filename = filename[filename.length - 1]

    var request = $.ajax({
        url: "counter.php?file=" + filename
    });

    request.done(function(msg) {
        alert("yes");
        window.location.href = "*****URL******"+filename;
    });

    request.fail(function(jqXHR, textStatus) {
        alert("no");
    });

    // if this is here, ajax works, but download fails
    return false;


});
});

显然填写您自己的网址。

【讨论】:

  • e.preventDefault() 和后来的 window.location.href 的组合实际上是有效的。 'return false;'甚至不再需要了。谢谢!
【解决方案2】:

这个呢

<a href="downloads/bla.zip" id="download" style="display:none"></a>
<span class="countDownload">bla</span>


$(document).ready(function() {

$("body").on("click", ".countDownload", function() {
    var filename = $("#download").attr("href");
    filename = filename.split("/");
    filename = filename[filename.length - 1]

    var request = $.ajax({
        url: "counter.php?file=" + filename
    });

    request.done(function(msg) {
        alert("yes");
    });

    request.fail(function(jqXHR, textStatus) {
        alert("no");
    });

    $("#download").trigger("click");
    return false;


});
});

首先它会通过你的ajax请求然后触发anchor的点击事件

【讨论】:

    【解决方案3】:

    您的 HTML:

    <div class="result"></div>
    <button url="downloads/bla.zip">Click to download the file</button>
    

    你的脚本:

    $(document).ready(function()
    {
        $('button').on('click',function()
        {
            var filename = $(this).attr('url');
            var request = $.ajax(
            {
                url: "download_file.php?file=" + filename
            });
            request.done(function(msg)
            {
                $('.result').html('Thank you for downloading!');
            });
            request.fail(function(jqXHR, textStatus)
            {
                $('.result').html('Download failed!');
            });
        });
    });
    

    download_file.php?file=downloads/bla.zip:

        //First find this file :)
    if(!empty($_POST['file']))
    {
        $dirpath = 'location/of/file/'; 
        if(file_exists($dirpath))
        {
            $file = $dirpath.$_POST['file'];
            header('Content-Description: Secure file download');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename=' . basename($file));
            header('Content-Transfer-Encoding: binary');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Pragma: public');
            header('Content-Length: ' . filesize($file));
            ob_clean();
            flush();
            readfile($file);
            //DO YOUR COUNTING SOMEWHERE HERE:
            exit;
        }
    }
    else
    {
        //LOG ERROR HERE:
        exit;
    }
    

    为了稍微保护您的文件,将此 .htaccess 放入您的下载文件夹:

    Order deny,allow
    Deny from all
    

    我没有测试上述内容。希望你能从这里自己弄清楚。祝你好运

    【讨论】:

    • 我对问题的解释明确表示不要使用 readfile()、fpassthru() 或类似的。
    • 当你使用退出时;函数它不应该计算两次。我使用类似的代码。
    • 怎么样?它被调用了两次,那么如果你使用 exit 有什么区别呢?无论如何它都会被调用。
    • 有多种方法可以防止多个请求。根据请求记录会话,或将其记录到数据库等。您可以轻松设置时间戳,然后当然检查每个文件的最后请求时间。如果我可以问,这些文件有多大?
    猜你喜欢
    • 2014-08-10
    • 2014-09-10
    • 2015-12-04
    • 2013-05-22
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    相关资源
    最近更新 更多