为什么 Apache 在我的一些 HTML 输出中插入注释


Why is Apache inserting comment into some of my HTML output?

在通过W3C的HTML5验证器运行我的代码时,我注意到我的一些文件在标签之前插入了以下注释:

<!-- This file should NOT be stored in the web root directory (or any sub-directory thereof) If this is not possible, place it in the 'include' directory and restrict access via Apache's .htaccess files -->

这似乎只发生在通过 POST 请求访问的页面上,尽管我无法确定任何原因,搜索也没有发现任何东西。

我正在使用 mod 重写,HTML 是从 webroot/views/和 webroot/include/的多个文件生成的,但其他类似生成的页面没有这个问题。

无论如何,我通常不会担心它,但是当发送 xml 请求以动态更新价格字段时,xml 返回结果(应该只是作为数字的价格值)以整个注释为前缀。

现在,我可以在我的应用程序代码中删除它,这就是我所做的,但我真的很想知道在什么情况下 Apache 决定将此注释注入到输出的 HTML 文件中。

作为参考,这是我发送/处理 xml 请求的 JS:

<script type="text/javascript">
/**
 * Updates the currently displayed price based on currently selected options
 * @param category_id   Id of currently selected category
 */
function updatePrice(category_id) {
    if (category_id === undefined || category_id < 1) {
        return false;
    }
    if (!document.getElementsByTagName) { return; }
    var aSelect = document.getElementsByTagName("SELECT");
    var data = [];
    data.push("category_id=" + category_id);
    for (var i = 0; i < aSelect.length; i++) {
        var sid = aSelect[i].id;
        if (sid !== undefined && sid.indexOf("select_") > -1) {
            data.push(sid + '=' + aSelect[i].value);
        }
    }
    data = data.join('&');
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            // Hack to remove Apache's auto-generated comment/warning at top of some pages
            var text = xmlhttp.responseText;
            text = (text.length > 0 ? text.substring(text.lastIndexOf('>') + 1).trim() : '');
            var price = document.getElementById("product-price");
            if (price != null) {
                price.value = (text.length < 1 ? 'N/A' : ('$' + text));
            }
        }
    }
    xmlhttp.open("POST", "rental_update_price.php", true);
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.send(data);
}
</script>

这是处理请求的 php 文件:

<?php
if (!isset($errors)) { $errors = array(); }
if (!isset($notifications)) { $notifications = array(); }
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (empty($_POST['category_id']) || !is_numeric($_POST['category_id'])) {
        die('Sorry, there has been a system error.');
    }
    $category_id = (int) $_POST['category_id'];
    require './includes/config.inc.php';
    require MYSQL;
    $att_tbl = selectWithCondition($dbc, 'att_table', 'rental_categories', 'id', $category_id, 'i', 'LIMIT 1');
    if ($att_tbl === FALSE) {
        die('Failed to retrieve product attribute table from database.');
    }
    // Retrieve all 'select' keys and values to query exact product id and price
    $selected = array();
    foreach($_POST AS $k=>$v) {
        if (strpos($k, 'select_') > -1) {
            // All select fields should be foreign key references, i.e. positive integers
            if (ctype_digit($v) && $v > 0) {
                $selected[(str_replace('select_', '', $k) . '_id')] = (int) $v;
            } else {
                $errors[$k] = 'Invalid value';
            }
        }
    }
    if (empty($selected)) {
        die('No columns selected.');
    }
    // TODO select price instead of id
    $q = "SELECT p.id FROM products p";
    $where = '';
    foreach($selected AS $k=>$v) {
        if (empty($where)) {
            $where = "t.$k=$v";
        } else {
            $where .= " AND t.$k=$v";
        }
    }
    $q .= " JOIN $att_tbl t ON t.product_id=p.id WHERE $where LIMIT 1";
    if (($r = $dbc->query($q))) {
        if ($row = $r->fetch_assoc()) {
            // Generate dummy price value for testing:
            echo number_format((((int) $row['id']) * 31) / 100, 2);
        }
        $r->close();
    } else {
        $notifications['error'] = 'A system error has occurred. The system administrator will be notified automatically.';
        $notifications['error_log'] = 'Error No: ' . $dbc->errno . '-' . $dbc->error;
    }
}
require MYSQL;

如果MYSQL是一个文件,请为其提供扩展名.php这样它就不会绕过 PHP 解释器。

我认为当您包含未解析的文件时,PHP 确实会打印警告。

回答我自己的问题,因为它是你寻找几天的问题之一,当你最终崩溃并询问时,它几乎立即变得明显。

在我的 MYSQL

文件中,我把该注释放在顶部,甚至在 php 标签之前,在某些情况下,MYSQL 文件包含在任何其他 HTML 输出之前,然后导致显示该注释。

将注释移动到 php 标记内,使其不被视为 HTML 可以解决此问题。

感谢所有发表评论的人。