【问题标题】:Serving download after form submit w/ validation提交表单后提供下载并进行验证
【发布时间】:2011-09-22 23:16:37
【问题描述】:

我已经在 .php 中创建了一个非常简单的下载代码兑换器(感谢这里的帮助),我很难弄清楚如果验证成功,提供下载的最佳方式是什么。基本上——

用户输入无效代码 -> 页面刷新并显示错误消息。 用户输入有效代码 -> 提供下载“另存为” -> 刷新页面。

当时我正在使用http://www.zubrag.com/scripts/download.php 提供文件,但一旦开始下载,我的表单会刷新页面但只加载一半内容?!

这是我做的带有 PHP 脚本的表单。

<div class="dcrForm">
    <p>Have a physical copy of this release? Claim your digital download by entering your Download Code below.</p>
    <form  action="index.php" method="post">
        <input type="text" name="code" class="dcrInput" value="">
        <input type="submit" name="harrisSubmit" class="dcrSubmit" value="Submit">
    </form>
<?php
    include("scripts/dcr_config.php");
    $code="";
    $log="";

    if (isset($_POST['harrisSubmit']))
    {
        $code=$_POST['code'];

        $link = mysql_connect($hostname, $dbusername, $dbpassword);
        mysql_select_db("$databasename");

        $query = "select count from $harris where code='$code'";
        if ($q=mysql_query($query))
            if ($r=mysql_fetch_array($q)){
                if ($r[0]<3)
                {
                    $subquery="update $tbname set count='".($r[0]+1)."' where code='$code'";
                    mysql_query($subquery);
                    ?><script>window.location.href="download.php?f=test.txt";</script><?php
                }
            }
        $log="<p>Invalid code. Try Again.</p>";
    }
    echo $log."";
?>
</div>

有没有人知道提供下载的最佳方式是什么?我知道目前拥有该文件位置的任何人都可以下载该文件,但我不确定如何保护我

【问题讨论】:

    标签: php http-headers download page-refresh


    【解决方案1】:

    很高兴你能做到这一点!

    如果您要将用户重定向到下载脚本,则该脚本需要附加某种令牌以防止未经授权的下载,基本上是重新验证给定的代码或令牌。

    在上面的脚本中,你可以这样做:

    <?php
    
    include "scripts/dcr_config.php";
    $code = "";
    $log  = "";
    
    if (isset($_POST['harrisSubmit'])) {
        $code = trim($_POST['code']);
    
        $link = mysql_connect ( $hostname, $dbusername, $dbpassword );
        mysql_select_db ( "$databasename" );
    
        $code = mysql_real_escape_string($code); // very important! protects against exploits
    
        $query = "select count from $harris where code='$code'";
        if ($q = mysql_query ( $query )) {
            if ($r = mysql_fetch_array ( $q )) {
                if ($r [0] < 3) {
                    $subquery = "update $tbname set count='" . ($r [0] + 1) . "' where code='$code'";
                    mysql_query ( $subquery );
    
                    $file = '/path/to/protecteddownload.txt';
    
                    // send file to browser as a download dialog
                    // no content can be output prior to these header() calls
                    header('Content-type: application/octet-stream');
                    header('Content-Disposition: attachment; filename="file.txt"');
                    header('Content-Length: ' . filesize($file));
                    header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
                    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
    
                    echo file_get_contents($file);
                    exit; // terminate script
                } else {
                    $log = 'Sorry, this code has already been redeemed.';
                }
            } else {
                $log = 'Invalid download code.  Try again.';
            }
        } else {
            // query failed
            $log = 'An error occurred validating your code, please try again later.';
        }
    
        $log = "<p>Invalid code. Try Again.</p>";
    }
    
    ?>
    
    <?php if (isset($log) && $log != ''): ?>
    <strong class="error"><?php echo $log ?></strong>
    <?php endif; ?>
    
    <div class="dcrForm">
    <p>Have a physical copy of this release? Claim your digital download by
    entering your Download Code below.</p>
    <form action="index.php" method="post"><input type="text" name="code"
        class="dcrInput" value=""> <input type="submit" name="harrisSubmit"
        class="dcrSubmit" value="Submit"></form>
    </div>
    

    下载脚本可能与我上面的一些类似。 此示例的关键在于您使用 file_get_contents 提供的文件无法从 Web 访问。只有在输入有效代码时才发送它。

    【讨论】:

    • 您好,再次绘制,谢谢,这是一个非常有用的项目。我已经尝试过您的上述解决方案,但即使我将 $file 设置为可从网络访问的位置并将文件名更改为我指向的文件名,也不会提供下载并且页面会刷新并且只加载一半!
    • 您使用的是绝对路径还是相对路径?
    • 我稍微改变了您的代码结构,因为如果您想发送标头,在执行此操作之前不能输出 html 或空格,特别是如果我们要提供下载服务。该代码块上方是否还有其他 HTML 发送示例中未显示的标头?如果是这样,请确保提供下载的脚本在提供文件之前没有其他输出。很抱歉之前没有回复,我一定是错过了收件箱消息。
    • dizas 我使用的是绝对路径。 @drew010 没问题,你一直回复真是太好了。代码就在 index.php 页面上,就在 jsfiddle.net/jeUmJ 这样的表单下方,但它听起来不像是在正确的位置?
    • jsfiddle 很慢,所以我在 pastebin here 上发布了更新。我所做的是将所有 php 和验证移到文件的开头。现在您应该没有错误尝试提供下载。看看这是否有效。它还在开头设置错误,如果代码无效,稍后将显示它。
    【解决方案2】:

    我只有一个简单的问题,这个文件有多大?这可能是在将文件读取到浏览器时遇到 php 超时的情况吗?

    您可以使用 php 设置来确认这一点 (http://php.net/manual/en/function.set-time-limit.php)。

    只要我的 2 美分

    【讨论】:

    • 我从没想过,它是一个大约 250MB 的 .zip
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多