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

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

在通过 W3C 的 HTML 验证程序运行我的代码时 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/includes/ 的多个文件生成的,但类似生成的其他页面不会有这个问题。

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

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

作为参考,这是我对 send/handle 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' : ('

这是处理请求的 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;
    }
}
+ text)); } } } xmlhttp.open("POST", "rental_update_price.php", true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send(data); } </script>

这是处理请求的 php 文件:

$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 解决了问题。

感谢所有发表评论的人。