【问题标题】:PHP generate file for download then redirectPHP生成文件以供下载然后重定向
【发布时间】:2010-10-23 18:56:54
【问题描述】:

我有一个 PHP 应用程序,它创建一个强制使用标题下载的 CSV 文件。这是代码的相关部分:

header('Content-Type: application/csv'); 
header("Content-length: " . filesize($NewFile)); 
header('Content-Disposition: attachment; filename="' . $FileName . '"'); 
echo $content;
exit(); 

我想做的是在构建文件并发送下载提示后将用户重定向到新页面。预期只是在末尾添加header("Location: /newpage") 不起作用,所以我不确定如何安装它。

【问题讨论】:

    标签: php redirect header


    【解决方案1】:

    您发送的标头是 HTTP 标头。浏览器将其作为页面请求并将其作为页面处理。在您的情况下,它需要下载一个页面。

    所以添加一个重定向头会混淆整个下载文件的过程(因为头被收集,生成一个头然后发送到浏览器,你可以通过设置多个重定向头IIRC来尝试)

    【讨论】:

      【解决方案2】:

      我不认为这可以做到 - 尽管我不是 100% 确定。

      常见的情况(例如在流行的下载站点中)是相反的:首先您转到 after 页面,然后开始下载。

      因此,将您的用户重定向到 final 页面(除其他外):

      您的下载应该会自动开始。如果没有点击[a href="create_csv.php"]here[/a]

      关于启动下载(例如自动调用 create_csv.php),您有很多选择:

      • HTML:[meta http-equiv="refresh" content="5;url=http://site/create_csv.php"]
      • Javascript:location.href = 'http://site/create_csv.php';
      • iframe:[iframe src="create_csv.php"][/iframe]

      【讨论】:

      • 如何在启动已经启动并且drupal 已经显示页面时执行此操作? javascript的代码是什么?
      • 这不是问题的答案。它特别询问如何在下载后重定向到不同的页面。如果单用 PHP 不能解决,建议用 JavaScript 加 JavaScript 的解决方案。
      【解决方案3】:

      但请记住,为 IE 用户自动启动可下载文件将触发安全警告选项卡。 Daremon 概述的所有三种方法都会显示此警告。你根本无法解决这个问题。如果您提供真实的链接,您会得到更好的服务。

      【讨论】:

        【解决方案4】:

        我找到了一种解决方法,它依赖于 javascript,因此它并不完全安全,但对于不安全的关键站点,它似乎可以工作。

        有一个带有标题为“下载”按钮的表单,其动作设置为指向下载脚本,然后使用 javascript 在 onsubmit 处理程序上放置一些东西,该处理程序去除下载按钮并替换屏幕上的消息。下载应该仍然发生并且屏幕会改变。显然,如果下载脚本有问题,那么即使它没有触发,它仍然看起来下载成功,但这是我目前最好的。

        【讨论】:

          【解决方案5】:

          您可以尝试重定向到 URL 以及表示文件内容的参数。并且在重定向中可以输出文件内容供下载。

          【讨论】:

            【解决方案6】:

            在真正需要的情况下很容易做到。

            但是您需要在 JavaScript 和 cookie 方面做一些工作:

            在 PHP 中你应该添加设置一个 cookie

            header('Set-Cookie: fileLoading=true'); 
            

            然后在您调用下载的页面上,您应该使用 JS 跟踪(例如每秒一次)是否有类似的 cookie(这里使用了插件 jQuery cookie):

            setInterval(function(){
              if ($.cookie("fileLoading")) {
                // clean the cookie for future downoads
                $.removeCookie("fileLoading");
            
                //redirect
                location.href = "/newpage";
              }
            },1000);
            

            现在,如果文件开始被下载,JS 会识别它并在 cookie 被删除后重定向到所需的页面。

            当然,你可以告诉你需要浏览器接受cookies、JavaScript等等,但它可以工作。

            【讨论】:

              【解决方案7】:

              这是一个很老的问题,但这是我通过 JS 实现的。

              // Capture the "click" event of the link.
              var link = document.getElementById("the-link");
              link.addEventListener("click", function(evt) {
                // Stop the link from doing what it would normally do.
                evt.preventDefault();
                // Open the file download in a new window. (It should just
                // show a normal file dialog)
                window.open(this.href, "_blank");
                // Then redirect the page you are on to whatever page you
                // want shown once the download has been triggered.
                window.location = "/thank_you.html";
              }, true);
              

              通过 - https://www.daniweb.com/web-development/php/threads/463652/page-not-redirecting-after-sending-headers-in-php

              【讨论】:

              • 不幸的是,在按照问题要求生成文件后,这并没有重定向,而是立即重定向。因此,如果下载更改了应该在重定向页面中显示的数据,它将无法正常工作。
              【解决方案8】:

              使用以下命令启动包含 CSV 下载的 PHP 文件:

              <a onclick="popoutWin(\'csvexport.php\')" >Download CSV File</a>
              

              <input name="newThread" type="button" value="Download CSV File"
                      onclick="popoutWin(\'csvexport.php\')" />
              

              JavaScript 函数 popoutWin 在哪里

              /*
               * Popout window that self closes for use with downloads
               */
              function popoutWin(link){
                  var popwin = window.open(link);
                  window.setTimeout(function(){
                      popwin.close();
                  }, 500);
              }
              

              这将打开一个窗口,显示 CSV 下载提示,然后立即关闭窗口,只留下提示。

              【讨论】:

              • 请注意,如果 php 代码(上面的 csvexport.php)需要时间运行,您可能需要将 popoutWin() 时间增加到更大的值,例如 5000,否则窗口将在脚本执行之前关闭完成,用户将没有机会选择保存导出文件的目录。
              • 使用这样的随机时间变量是非常不明智的。
              • 感谢@jvakuiler 的反馈 - 我很高兴能更好地理解为什么不这样做。请为我指明正确的方向,如果需要,我会在了解您的建议后删除此提议的方法。
              • 嘿@Clinton 感谢您的留言,我很乐意详细说明。首先,您不能假设正在打开的窗口会像您建议的那样在 500 毫秒内加载。一般来说,您不能假设窗口会在任何时间内成功打开。下载也可能失败,除了锚点损坏之外,用户没有任何信息。
              • 我想诀窍是使用一个在加载完成后立即关闭的窗口。不过,这方面的 Javascript 可能有点困难。
              【解决方案9】:

              更新:新解决方案:

              <a id="download-link" 
                 href="https://example.com/uploads/myfile.pdf" 
                 class="btn">Download</a>
              

              <script>
                  jQuery(document).ready(function(  ) {
                      jQuery("#download-link").click(function(e) {
                          e.preventDefault(); 
                          var url = jQuery(this).attr('href');
                          var _filename = url.split('/');
                          _filename = _filename[_filename.length - 1];
                          console.log(_filename);
                      
                          fetch(url, {
                              method: 'POST',
                              headers: {
                                  'Content-Type': 'application/json; charset=utf-8'
                              },
                          })
                          .then(response => response.blob())
                          .then(response => {
                              const blob = new Blob([response], {type: 'application/pdf'});
                              const downloadUrl = URL.createObjectURL(blob);
                              const a = document.createElement("a");
                              a.href = downloadUrl;
                              a.download = _filename;
                              document.body.appendChild(a);
                              a.click();
                          });
                      
                      });
                  });
              </script>
              

              Source

              旧答案:

              答案如下:
              这是工作!
              您需要三个不同的代码部分:

              HTML

              <a id="download_btn" class="btn btn-primary" href="?file=filename&download=1">Download<&/a>
              

              **jQuery**
              $('#download_btn').click(function(){
                  window.location.href = '<?=base_url()?>/?file=<?=$file;?>&download=1';
              }).focusout (function(){
                  window.location.href = '<?=base_url()?>';
                  return false;
              });
              

              **PHP**
                      if(isset($_GET['download']) && isset($_GET['file'])){
                          
                          $zip_path = 'path_to/'.$_GET['file'].'.zip';
              
                          if(file_exists($zip_path)){
                              header('Content-Type: application/zip');
                              header('Content-Disposition: attachment; filename="'.basename($zip_path).'"');
                              header('Content-Length: ' . filesize($zip_path));
                              header('Location: '.$zip_path);
                          }
              
                      }
              

              【讨论】:

              【解决方案10】:
              <?php 
                  function force_file_download($filepath, $filename = ''){
                      if($filename == ''){
                          $filename = basename($filepath);
                      }
              
                      header('Content-Type: application/octet-stream');
                      header("Content-Transfer-Encoding: Binary"); 
                      header("Content-disposition: attachment; filename=\"" . $filename . "\""); 
                      readfile($filepath); // do the double-download-dance (dirty but worky)  
                  }
              
                  force_file_download('download.txt');
              ?>
              <script type="text/javascript">
                  location = 'page2.php'
              </script>
              

              这是一个使用 javascript 的解决方案。

              【讨论】:

              • 能否详细说明?
              • 是的,您强制使用 php 下载文件,一旦下载正在进行,JS 将评估并导致重定向到另一个页面(如原始问题所问)
              • 你测试过这个吗?这看起来好像末尾的脚本标记将成为(附加到)下载文件的一部分,并且不会重定向任何内容。
              【解决方案11】:

              嗯嗯……

              将下面的代码放在网站的主要 javascript 中。

               if (window.location.pathname == '/url_of_redirect/') {
                      window.open(location.protocol + '//' + location.hostname + '/url_of_download.zip', '_parent');
                  }
              

              解释: 它使用 php 将正常重定向到您将定义的某个 url,在 javascipt 中它说:如果路径名与重定向的路径相同'/url_of_redirect/'然后它会在新页面上打开 url,生成下载。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-06-20
                • 1970-01-01
                • 1970-01-01
                • 2011-07-31
                • 1970-01-01
                相关资源
                最近更新 更多