php - 是否可以从 PHP 文件发送 header ,这绝对没有任何作用

标签 php request-headers

在我提供音乐样本下载的页面上,我有几个 <a> href 指向 PHP 文件的标签。作为 GET 变量包含的各种数据允许下载正确的文件。通常 PHP 将响应典型的下载 header ,然后是 readfile()。 (代码如下,仅供引用)。这会导致干净的下载(或某些浏览器上的下载/播放对话框)。 “干净”是指下载完成,访问者页面没有受到干扰。

但是,万一请求的文件不可用,我不知道该怎么办。我知道这不应该发生,但如果发生了,我希望下载链接什么都不做。不幸的是,因为它是 <a>标记引用一个 PHP 文件,什么都不做会导致浏览器清除页面,并在地址栏中显示 PHP 文件的 URL。不是很好的访客体验!所以我想避免打扰页面并且在有错误请求时什么都不做。我将使用 javascript 提醒访问者出了什么问题,但我无法让错误的文件请求清除页面!

我想我已经通过发布一个标题('Location:#');当脚本检测到无法下载文件时。但几秒钟后,浏览器清除了该页面并显示了一条消息,指出该页面“重定向您的次数太多”。 (事实上​​ ,我的脚本日志充满了 100 多个条目,即使我只点击了一次标签。)

到目前为止,我唯一可行的解​​决方案(在请求“不可用”文件时不会打扰访问者页面的意义上起作用)是将我的下载 header 指向一个“虚拟”文件。实际的“silence.mp3”或“nosong.mp3”文件。但是有没有办法调用对调用页面不做任何事情的 header() 呢?简单地调用 exit 或 exit() 是行不通的(访问者页面被重定向为空白。)

这并不重要,但这是我通常为响应​​ d/l 请求而调用的代码...

function downloadFile($path) {
    $path_parts = pathinfo($path);
    $ext = strtolower($path_parts["extension"]); // don't need this.
    $fsize =fileExists($path);
    if ($fsize == 0) 
        {
         header('Location: #'); // this doesn't work!!! (too many redirectcts)
         exit;
         }

    //$dlname = $path_parts['filename'] . "." . strtolower($path_parts["extension"]);


    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Disposition: filename=\"" . $path_parts["basename"]."\"");
    header("Content-Type: application/x-file-to-save");
    header("Content-Transfer-Encoding: binary");
    if($fsize) header("Content-length: $fsize");
    $bytesRead = readfile($path);
    return $bytesRead;
    }   

最佳答案

如果您使用带有标准 anchor 标记的 HTTP/1.x,没有 JavaScript 或其他客户端拦截。 HTTP/1.0 204 No Content 状态 header 将导致用户代理在单击返回 204 状态 header 的链接时看起来好像什么也没发生。

HTTP/1.0 204 No Content
The server has fulfilled the request but there is no new information to send back. If the client is a user agent, it should not change its document view from that which caused the request to be generated. This response is primarily intended to allow input for scripts or other actions to take place without causing a change to the user agent's active document view. The response may include new metainformation in the form of entity headers, which should apply to the document currently in the user agent's active view.
Source: https://www.w3.org/Protocols/HTTP/1.0/spec.html#Code204

这也与 HTTP/1.1 协议(protocol)兼容。

我建议使用输出缓冲来确保您的应用程序不会错误地发送其他内容。此外,应该不需要发送 Content-Length header 。

function downloadFile($path) {
    if (!is_file($path) || !($fsize = filesize($path))) {
        header('HTTP/1.0 204 No Content');
        exit;
    }
    $path_parts = pathinfo($path);
    header('Cache-Control: public');
    header('Content-Description: File Transfer');
    header('Content-Disposition: filename="' . $path_parts['basename'] . '"');
    header('Content-Type: application/x-file-to-save');
    header('Content-Transfer-Encoding: binary');
    header('Content-length: ' . $fsize); //fsize already validated above.

    return readfile($path);
}

关于php - 是否可以从 PHP 文件发送 header ,这绝对没有任何作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56502654/

相关文章:

PHP和MySql的麻烦

PHP比较困惑

node.js - 两个http请求能走到一起吗?如果可以,nodeJS 服务器如何处理它?

java - 未知的授权 header - 错误 401

php - 我的 android 登录/注册 PHP 服务器出现问题

php - 使用 PHP 和 jQuery 进行拖放

PHP:在特定日期自动更新数据库字段,没有通过 cronjob 的脚本

spring - @RequestHeader 在 spring 中不接受假 header

C++ Libcurl 无法清除 header

java - 如何设置请求 header (x-amz-服务器端加密 : aws:kms) while saving file to S3 in Java code?