javascript responseText 有效,但 responseXML 始终为空
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14336381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
responseText works but responseXML is always null
提问by dijkstra8x
I've looked through every answer i can find on here and can't solve this. I'm pretty sure I havn't missed anything obvious.
我已经浏览了我可以在这里找到的所有答案,但无法解决这个问题。我很确定我没有遗漏任何明显的东西。
I'm trying to load map markers based on lat longs. The problem is when I try to return the AJAX response as responseXML its always null, if i use responseText it works fine but obviously the next step doesn't work.
我正在尝试根据经纬度加载地图标记。问题是当我尝试将 AJAX 响应作为 responseXML 返回时,它始终为空,如果我使用 responseText 它工作正常,但显然下一步不起作用。
This is the PHP that generates the XML:
这是生成 XML 的 PHP:
<?php
header('Content-type: text/xml');
?>
<?xml version="1.0" encoding="ISO-8859-1"?>
<properties>
<![CDATA[
<?php
if ($body != null):
foreach ($body as $property): ?>
<property>
<lat><?php echo $property -> lat; ?></lat>
<long><?php echo $property -> long; ?></long>
<name><?php echo $property -> property_name; ?></name>
</property>
<?php endforeach;
endif; ?>
]]>
</properties>
I can see in Fiddler that the request is made ok
我可以在 Fiddler 中看到请求已完成
GET /letsgo/index.php/hotmaps/get_properties_ajax/22.270888501350186/22.288560098193066/114.13720860290528/114.19827713775635 HTTP/1.1
Entity Content-type: text/xml
GET /letsgo/index.php/hotmaps/get_properties_ajax/22.270888501350186/22.288560098193066/114.13720860290528/114.1982775137775633
实体内容类型:text/xml
Although when i view this in XML view in fiddler it appears to be empty,
虽然当我在 fiddler 的 XML 视图中查看它时,它似乎是空的,
here is the raw response
这是原始回复
HTTP/1.1 200 OK
Date: Tue, 15 Jan 2013 11:04:27 GMT
Server: Apache/2.4.2 (Win32) PHP/5.4.4
X-Powered-By: PHP/5.4.4
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 310
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<properties>
<![CDATA[
<property>
<lat>22.2776</lat>
<long>114.173</long>
<name>Kaxo Tower test</name>
</property>
<property>
<lat>22.2803</lat>
<long>114.16</long>
<name>Kuno Tower</name>
</property>
]]>
</properties>
Here is the create marker function that is called every time the map is moved
这是每次移动地图时调用的创建标记函数
// make the ajax request
function loadXMLDoc(downUrl){
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
//var propertiesXml = xmlhttp.responseText; // WORKS FINE!!
var propertiesXml = xmlhttp.responseXML; // ALWAYS null
//alert(propertiesXml);
var propertiesRows = propertiesXml.getElementsByTagName("property");
for (var i = 0; i < propertiesRows.length; i++) {
var propertiesRow = propertiesRows[i];
var xmlLat = propertiesRow.getElementsByTagName("lat")[0];
var xmlLong = propertiesRow.getElementsByTagName("long")[0];
var propertyLatLong = new google.maps.LatLng(parseFloat(xmlLat.firstChild.data),parseFloat(xmlLat.firstChild.data));
// create each marker
createMarker(propertyLatLong);
}
? }
}
xmlhttp.open("GET", downUrl, false); // false or true? makes no difference
xmlhttp.setRequestHeader("Content-type", "text/xml");
xmlhttp.send();
}
and this is the error i get for feeding getElementsByTagName with null, Chrome console says
Chrome 控制台说,这是我为 getElementsByTagName 提供 null 时得到的错误
Uncaught TypeError: Cannot call method 'getElementsByTagName' of null
未捕获的类型错误:无法调用 null 的方法“getElementsByTagName”
This is running on my local Apache
这是在我本地的 Apache 上运行
Any suggestions?
有什么建议?
/** UPDATE - WORKING CODE **/
/** 更新 - 工作代码 **/
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=APIKEYHERE&sensor=false">
</script>
<script type="text/javascript">
// initialise map
function initialize() {
// set starting latlong
var myLatlng = new google.maps.LatLng(22.2776, 114.173);
// set initial map options
var mapOptions = {
center: myLatlng,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// create the map
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// listen for changes in map bounds - after map has stopped moving!!
google.maps.event.addListener(map,'idle', function () {
loadByBounds(map);
});
}
// if the bounds have changed
function loadByBounds(map) {
var bounds = map.getBounds();
var swPoint = bounds.getSouthWest();
var nePoint = bounds.getNorthEast();
// specific co ordinates
var swLat = swPoint.lat();
var swLng = swPoint.lng();
var neLat = nePoint.lat();
var neLng = nePoint.lng();
var downUrl = "<?php echo site_url('hotmaps/get_properties_ajax'); ?>/"+swLat+"/"+neLat+"/"+swLng+"/"+neLng;
// load the
loadXMLDoc(downUrl, map);
// clear icons outside of bounding box
//....
}
// make the ajax request
function loadXMLDoc(downUrl, map){
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var propertiesXml = xmlhttp.responseText; // WORKS FINE!!
// remove whitespaces from start and end (.trim() doesnt work)
propertiesXml = propertiesXml.replace(/^\s+|\s+$/g,'');
// manually parse to XML DOM object
var parser = new DOMParser();
var xmlDoc;
try {
xmlDoc = parser.parseFromString (propertiesXml, "text/xml");
} catch (e) {
alert ("XML parsing error.");
return false;
};
//console.log(xmlDoc);
// get each property
var propertiesRows = xmlDoc.getElementsByTagName("property");
//alert(console.log(propertiesRows));
for (var i = 0; i < propertiesRows.length; i++) {
var propertiesRow = propertiesRows[i];
var xmlLat = propertiesRow.getElementsByTagName("lat")[0];
var xmlLong = propertiesRow.getElementsByTagName("long")[0];
var propertyLatLong = new google.maps.LatLng(parseFloat(xmlLat.firstChild.data),parseFloat(xmlLong.firstChild.data));
// create each marker
createMarker(propertyLatLong, map);
}
}
}
xmlhttp.open("GET", downUrl, false);
xmlhttp.setRequestHeader("Content-type", "text/xml");
xmlhttp.send();
}
// create new markers
function createMarker(propertyLatLong, map){
var dynamicMarker = new google.maps.Marker({
map:map,
draggable:false,
position: propertyLatLong
});
debugger;
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
回答by povilasp
You can try parsing XML yourself:
您可以尝试自己解析 XML:
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml");
Like this.
像这样。
回答by JEY
your tags are in CDATA section so they are ignore as tag by the parser.
您的标签位于 CDATA 部分,因此解析器将它们作为标签忽略。
回答by Lemonade
I wonder why you want the parser to skip almost your entire http response body, it seems there is no need, it's not containing anything that could be misinterpreted. It even is the data you want to get parsed, that you hideaway in your example for no apparent reason.
我想知道为什么您希望解析器几乎跳过整个 http 响应主体,似乎没有必要,它不包含任何可能被误解的内容。它甚至是您想要解析的数据,您无缘无故地隐藏在您的示例中。
Look here for some explanation of CDATA: http://www.w3schools.com/xml/xml_cdata.asp
在这里查看 CDATA 的一些解释:http: //www.w3schools.com/xml/xml_cdata.asp
You could try commenting out the opening and closing CDATA statement like mentioned here: http://de.selfhtml.org/html/xhtml/unterschiede.htm
您可以尝试注释掉这里提到的打开和关闭 CDATA 语句:http: //de.selfhtml.org/html/xhtml/unterschiede.htm
They also state, that the XML parser assumes UTF-8 encoding by default and will refuse parsing if not configured correctly, and that overwriting the exspected type via the response header is not recommended.
他们还指出,XML 解析器默认采用 UTF-8 编码,如果配置不正确,将拒绝解析,并且不建议通过响应头覆盖预期类型。
I prefer to avoid opening and closing php blocks inside block-statements the way you did it, but I'm not quite up-to-date with the latest coding conventions, so I may be wrong on that one.
我更喜欢避免像您那样在块语句中打开和关闭 php 块,但是我对最新的编码约定不是很了解,所以我可能是错的。
<?php
header('Content-type: text/xml');
header ('Cache-Control: no-cache');
header ('Cache-Control: no-store' , false);
$response ='<?xml version="1.0" encoding="UTF-8"?>
<properties>';
if ($body != null):
foreach ($body as $property):
$response .='<property>
<lat>'.$property->lat.'</lat>
<long>'.$property->long'.</long>
<name>'.$property->property_name.'</name>
</property>';
endforeach;
endif;
$response .='</properties>';
echo responseText;
?>