服务器如何发回多值响应?
比如希望一次发回
1、所选商品的一个串描述
2、商品的数字价格
3、一组指示商品相关信息的URL
你可能会用
1、XML
2、CSV(逗号分隔值),有可能Javascript不会正确的解释数据。
3、格式化为XHTML,再使用innerHTML属性。
实际上,innerHTML只是对web应用的客户端来说简单,服务器必须做大量额外工作。这种格式之特定于网站上某个单独的页面。
CSV 和XML速度都很快,但是当新的需求出现,比如服务器改变数据格式,或者请求不同的信息,你并不能总提前知道从服务器得到的数据有怎么样的结构,即使知道,这种格式也可能会改变。而XML是自描述的。
<?xml version=\"1.0\"?>
<item id=\"itemGuitar\">
<category>
<name>Manufacturer</name>
<value>Gibson</value>
</category>
<category>
<name>Model</name>
<value>Les Paul Standard</value>
</category>
<category>
<name>Description</name>
<value>Pete Townshend once played this guitar while his own axe was in the shop having bits of drumkit removed from it.</value>
</category>
<category>
<name>Price</name>
<value>5695.99</value>
</category>
<category type=\"list\">
<name>URLs</name>
<value>http://www.thewho.com/</value>
<value>http://en.wikipedia.org/wiki/Pete_Townshend</value>
</category>
</item>",
'itemShades' =>
"<?xml version=\"1.0\"?>
<item id=\"itemGuitar\">
<category>
<name>Description</name>
<value>Yoko Ono's sunglasses. While perhaps not valued much by Beatles fans this pair is rumored to have been licked by John Lennon.</value>
</category>
<category>
<name>Color</name>
<value>Black</value>
</category>
<category>
<name>Price</name>
<value>258.99</value>
</category>
<category type=\"list\">
<name>Worn By</name>
<value>John Lennon</value>
<value>Ringo Starr</value>
<value>Yoko Ono</value>
</category>
<category type=\"list\">
<name>URLs</name>
<value>http://www.beatles.com/</value>
<value>http://johnlennon.com/</value>
<value>http://www.yoko-ono.com/</value>
</category>
</item>
function displayDetails() {
if (request.readyState == 4) {
if (request.status == 200) {
var detailDiv = document.getElementById("description");
// Remove existing item details (if any)
for (var i=detailDiv.childNodes.length; i>0; i--) {
detailDiv.removeChild(detailDiv.childNodes[i-1]);
}
// Add new item details
var responseDoc = request.responseXML;
var categories = responseDoc.getElementsByTagName("category");
for (var i=0; i<categories.length; i++) {
var category = categories[i];
var nameElement = category.getElementsByTagName("name")[0];
var categoryName = nameElement.firstChild.nodeValue;
var categoryType = category.getAttribute("type");
if ((categoryType == null) || (categoryType != "list")) {
var valueElement = category.getElementsByTagName("value")[0];
var categoryValue = valueElement.firstChild.nodeValue;
var p = document.createElement("p");
var text = document.createTextNode(
categoryName + ": " + categoryValue);
p.appendChild(text);
detailDiv.appendChild(p);
} else {
var p = document.createElement("p");
p.appendChild(document.createTextNode(categoryName));
var list = document.createElement("ul");
var values = category.getElementsByTagName("value");
for (var j=0; j<values.length; j++) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(
values[j].firstChild.nodeValue));
list.appendChild(li);
}
detailDiv.appendChild(p);
detailDiv.appendChild(list);
}
}
}
}
}
---------------------------------
在处理childNodes数组时,()可以从后向前迭代。比如调用removeChild()时,提供给这个方法的节点会立即从相应父节点删除。这也说明,所删除节点的所有引用,比如说在一个包含元素子节点的数组中,都必须更新。由于所指向的子节点不复存在,被删除的这个节点之后的所有子节点就必须在数组中上移。
---------------------------------
但是XML太复杂。还好有JSON。Javascript对象已经是动态的,因为他们不是编译对象。
function isArray(arg) {
if (typeof arg == 'object') {
var criteria = arg.constructor.toString().match(/array/i);
return (criteria != null);
}
return false;
}
function displayDetails() {
if (request.readyState == 4) {
if (request.status == 200) {
var detailDiv = document.getElementById("description");
var itemDetails = eval('(' + request.responseText + ')');
// Remove existing item details (if any)
for (var i=detailDiv.childNodes.length; i>0; i--) {
detailDiv.removeChild(detailDiv.childNodes[i-1]);
}
// Add new item details
for (var property in itemDetails) {
var propertyValue = itemDetails[property];
if (!isArray(propertyValue)) {
var p = document.createElement("p");
p.appendChild(
document.createTextNode(property + ": " + propertyValue));
detailDiv.appendChild(p);
} else {
var p = document.createElement("p");
p.appendChild(document.createTextNode(property + ":"));
var list = document.createElement("ul");
for (var i=0; i<propertyValue.length; i++) {
var li = document.createElement("li");
li.appendChild(document.createTextNode(propertyValue[i]));
list.appendChild(li);
}
detailDiv.appendChild(p);
detailDiv.appendChild(list);
}
}
}
}
}
------------------------------
eval()函数告诉Javascript具体计算文本。
alert(eval(“2”+“2”)); 返回4
但是eval()函数会计算任何代码,完全不考虑导致什么后果。所以需要解析服务器的响应,而不只是直接计算。
可以从json.org下载一个json2.js的脚本,然后使用以下命令来解析JSON的数据。
var itemDetails=JSON.parse(request.responseText);
更新以上的js来使用JSON.parse()而不是eval()
-------------------------------
完成web编程时,安全总是一个重要问题。