You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP输出XML无效导致JS读取xmlDoc为空的问题及解决方法

PHP返回XML无法被前端JS识别的问题修复方案

问题背景

需要实现JS+PHP联动,将数据库中的数据渲染为前端表格,过程中遇到PHP返回的XML无法被JS正常解析的问题。

原始代码

初始PHP代码(两种XML生成方案均失效)

<?php
$serverName = "localhost";
$userName = "***";
$password = "***";
$DBName = "DataBase1";

// Connect to DB
$connection = mysqli_connect($serverName, $userName, $password, $DBName);
if (!$connection)
{
    die("Connection failed: " . mysqli_connect_error());
} else {
    //echo "Connected to DB<br>";
}

// Collect data
$selectionSD = $connection->query("SELECT * FROM `SensorData`");
$selectionSL = $connection->query("SELECT * FROM `SensorLog`");

// Generating XML file
//$xmlSD = new XMLWriter();
//$xmlSD->openUri("php://output");
//$xmlSD->startDocument();
//$xmlSD->setIndent(true);
//$xmlSD->startElement("SensorDataTable");
//while ($row = mysqli_fetch_assoc($selectionSD))
//{
//  $xmlSD->startElement("SensorData");
//      $xmlSD->startElement("ID");
//          $xmlSD->writeRaw($row["ID"]);
//      $xmlSD->endElement();
//      $xmlSD->startElement("SID");
//          $xmlSD->writeRaw($row["SID"]);
//      $xmlSD->endElement();
//      $xmlSD->startElement("Value");
//          $xmlSD->writeRaw($row["Value"]);
//      $xmlSD->endElement();
//      $xmlSD->startElement("Comment");
//          $xmlSD->writeRaw($row["Comment"]);
//      $xmlSD->endElement();
//      $xmlSD->startElement("DateTime");
//          $xmlSD->writeRaw($row["DateTime"]);
//      $xmlSD->endElement();
//  $xmlSD->endElement();
//}
//$xmlSD->endElement();
//header("Content-type: text/xml");
//$xmlSD->flush();
//$xmlSD->endDocument();

// Test code
$document = new DOMDocument('1.0', 'utf-8');
$document->formatOutput = true;

$root = $document->createElement('SensorDataTable');
$root = $document->appendChild($root);

while ($row = mysqli_fetch_assoc($selectionSD))
{
    $node = $document->createElement('SensorData');
    $node = $root->appendChild($node);

    // ID
    $dataNode = $document->createElement('ID');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["ID"]);
    $data = $dataNode->appendChild($data);
    // SID
    $dataNode = $document->createElement('SID');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["SID"]);
    $data = $dataNode->appendChild($data);
    // Value
    $dataNode = $document->createElement('Value');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["Value"]);
    $data = $dataNode->appendChild($data);
    // Comment
    $dataNode = $document->createElement('Comment');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["Comment"]);
    $data = $dataNode->appendChild($data);
    // DateTime
    $dataNode = $document->createElement('DateTime');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["DateTime"]);
    $data = $dataNode->appendChild($data);
}

echo $document->saveXML();

// Close DB connection
$connection->close();
?>

上述代码中注释段为首次使用的XMLWriter生成方案,未注释段为改用DOMDocument的测试方案,两种方案均未解决问题。

前端JS解析代码

console.log(xml);
let i;
const xmlDoc = xml.responseXML;
if (xmlDoc === null) {
    console.log("Failed to get response.");
}
let table = "<tr><th>SID</th><th>Value</th></tr>";
const x = xmlDoc.getElementsByTagName("SensorData");
for (i = 0; i < x.length; i++) {
    table += "<tr><td class='center'>" +
        x[i].getElementsByTagName("SID")[0].childNodes[0].nodeValue +
        "</td><td class='center'>" +
        x[i].getElementsByTagName("Value")[0].childNodes[0].nodeValue +
        "</td></tr>";
}
console.log("Changing DB display");
document.getElementById("DB").innerHTML = table;

代码中xml变量指向PHP接口的访问路径。

问题现象

  • JS运行时提示xmlDoc为null,但读取本地静态XML文件时逻辑完全正常
  • 直接访问PHP接口,输出的XML内容格式完全符合预期,如下:
<?xml version="1.0" encoding="utf-8"?>
<SensorDataTable>
  <SensorData>
    <ID>1</ID>
    <SID>1</SID>
    <Value>19.50</Value>
    <Comment>DHT_Temp</Comment>
    <DateTime>2021-10-04 12:57:51</DateTime>
  </SensorData>
  <SensorData>
    <ID>2</ID>
    <SID>2</SID>
    <Value>57.50</Value>
    <Comment>DHT_Humi</Comment>
    <DateTime>2021-10-04 12:57:55</DateTime>
  </SensorData>
  <SensorData>
    <ID>3</ID>
    <SID>1</SID>
    <Value>19.60</Value>
    <Comment>DHT_Temp</Comment>
    <DateTime>2021-10-04 12:58:29</DateTime>
  </SensorData>
  <SensorData>
    <ID>4</ID>
    <SID>2</SID>
    <Value>57.20</Value>
    <Comment>DHT_Humi</Comment>
    <DateTime>2021-10-04 12:58:32</DateTime>
  </SensorData>
</SensorDataTable>

根因分析

PHP默认返回的Content-Type响应头为text/html,浏览器接收到响应后不会将其识别为XML格式,因此XMLHttpRequest.responseXML属性会返回null。

修复方案

在PHP输出XML内容前,添加响应头声明指定返回内容格式为XML:header("Content-type: text/xml");

修复后的完整PHP代码

<?php
$serverName = "localhost";
$userName = "***";
$password = "***";
$DBName = "LIDAc";

// Connect to DB
$connection = mysqli_connect($serverName, $userName, $password, $DBName);
if (!$connection)
{
    die("Connection failed: " . mysqli_connect_error());
}

// Collect data
$selectionSD = $connection->query("SELECT * FROM `SensorData`");
$selectionSL = $connection->query("SELECT * FROM `SensorLog`");

// Generate XML file
$document = new DOMDocument('1.0', 'utf-8');
$document->formatOutput = true;

$root = $document->createElement('SensorDataTable');
$root = $document->appendChild($root);

while ($row = mysqli_fetch_assoc($selectionSD))
{
    $node = $document->createElement('SensorData');
    $node = $root->appendChild($node);

    // ID
    $dataNode = $document->createElement('ID');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["ID"]);
    $data = $dataNode->appendChild($data);
    // SID
    $dataNode = $document->createElement('SID');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["SID"]);
    $data = $dataNode->appendChild($data);
    // Value
    $dataNode = $document->createElement('Value');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["Value"]);
    $data = $dataNode->appendChild($data);
    // Comment
    $dataNode = $document->createElement('Comment');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["Comment"]);
    $data = $dataNode->appendChild($data);
    // DateTime
    $dataNode = $document->createElement('DateTime');
    $dataNode = $node->appendChild($dataNode);
    $data = $document->createTextNode($row["DateTime"]);
    $data = $dataNode->appendChild($data);
}

header("Content-type: text/xml");

echo $document->saveXML();

// Close DB connection
$connection->close();
?>

内容的提问来源于stack exchange,提问作者Lenny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 02:54:02