嗨,我正在尝试使用javascript构建一个rss阅读器。除了超链接之外,一切都正常运行。我需要传递一个变量来保存每个列表项的url。任何意见,将不胜感激。谢谢。
xml ---------------------------
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>CNN RSS Feed</title>
<link>http://rss.cnn.com/rss/cnn_world.rss</link>
<description>Feeds from Army Public Affairs</description>
<pubDate>Tue, 11 May 2010 22:04:03 GMT</pubDate>
<language>en-us</language>
<item>
<title>U.S. ambassador to mark Hiroshima</title>
<link>http://www.cnn.com/2010/WORLD/asiapcf/08/05/japan.us.hiroshima.presence/index.html?eref=rss_world&utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+rss%2Fcnn_world+%28RSS%3A+World%29</link>
<pubDate>June 24, 2010</pubDate>
<source url="http://rss.cnn.com/rss/cnn_world.rss">CNN</source>
</item>
<item>
<title>Study: Nearly 1.3 million Mexicans in capital don't have running water</title>
<link>http://www.cnn.com/2010/WORLD/americas/08/04/mexico.water.supply/index.html?eref=rss_world&utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+rss%2Fcnn_world+%28RSS%3A+World%29</link>
<pubDate>13 July 2010</pubDate>
<source url="http://rss.cnn.com/rss/cnn_world.rss">CNN</source>
</item>
</channel>
</rss>
//JavaScript File
/OBJECTS
//objects inside the RSS2Item object
function RSS2Enclosure(encElement)
{
if (encElement == null)
{
this.url = null;
this.length = null;
this.type = null;
}
else
{
this.url = encElement.getAttribute("url");
this.length = encElement.getAttribute("length");
this.type = encElement.getAttribute("type");
}
}
function RSS2Guid(guidElement)
{
if (guidElement == null)
{
this.isPermaLink = null;
this.value = null;
}
else
{
this.isPermaLink = guidElement.getAttribute("isPermaLink");
this.value = guidElement.childNodes[0].nodeValue;
}
}
function RSS2Source(souElement)
{
if (souElement == null)
{
this.url = null;
this.value = null;
}
else
{
this.url = souElement.getAttribute("url");
this.value = souElement.childNodes[0].nodeValue;
}
}
//object containing the RSS 2.0 item
function RSS2Item(itemxml)
{
//required
this.title;
this.link;
this.description;
//optional vars
this.author;
this.comments;
this.pubDate;
//optional objects
this.category;
this.enclosure;
this.guid;
this.source;
var properties = new Array("title", "link", "description", "author", "comments", "pubDate");
var tmpElement = null;
for (var i=0; i<properties.length; i++)
{
tmpElement = itemxml.getElementsByTagName(properties[i])[0];
if (tmpElement != null)
eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
}
this.category = new RSS2Category(itemxml.getElementsByTagName("category")[0]);
this.enclosure = new RSS2Enclosure(itemxml.getElementsByTagName("enclosure")[0]);
this.guid = new RSS2Guid(itemxml.getElementsByTagName("guid")[0]);
this.source = new RSS2Source(itemxml.getElementsByTagName("source")[0]);
}
//objects inside the RSS2Channel object
function RSS2Category(catElement)
{
if (catElement == null)
{
this.domain = null;
this.value = null;
}
else
{
this.domain = catElement.getAttribute("domain");
this.value = catElement.childNodes[0].nodeValue;
}
}
//object containing RSS image tag info
function RSS2Image(imgElement)
{
if (imgElement == null)
{
this.url = null;
this.link = null;
this.width = null;
this.height = null;
this.description = null;
}
else
{
imgAttribs = new Array("url","title","link","width","height","description");
for (var i=0; i<imgAttribs.length; i++)
if (imgElement.getAttribute(imgAttribs[i]) != null)
eval("this."+imgAttribs[i]+"=imgElement.getAttribute("+imgAttribs[i]+")");
}
}
//object containing the parsed RSS 2.0 channel
function RSS2Channel(rssxml)
{
//required
this.title;
this.link;
this.description;
//array of RSS2Item objects
this.items = new Array();
//optional vars
this.language;
this.copyright;
this.managingEditor;
this.webMaster;
this.pubDate;
this.lastBuildDate;
this.generator;
this.docs;
this.ttl;
this.rating;
//optional objects
this.category;
this.image;
var chanElement = rssxml.getElementsByTagName("channel")[0];
var itemElements = rssxml.getElementsByTagName("item");
for (var i=0; i<itemElements.length; i++)
{
Item = new RSS2Item(itemElements[i]);
this.items.push(Item);
//chanElement.removeChild(itemElements[i]);
}
var properties = new Array("title", "link", "description", "language", "copyright", "managingEditor", "webMaster", "pubDate", "lastBuildDate", "generator", "docs", "ttl", "rating");
var tmpElement = null;
for (var i=0; i<properties.length; i++)
{
tmpElement = chanElement.getElementsByTagName(properties[i])[0];
if (tmpElement!= null)
eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
}
this.category = new RSS2Category(chanElement.getElementsByTagName("category")[0]);
this.image = new RSS2Image(chanElement.getElementsByTagName("image")[0]);
}
//PROCESSES
//uses xmlhttpreq to get the raw rss xml
function getRSS()
{
//call the right constructor for the browser being used
if (window.ActiveXObject)
xhr = new ActiveXObject("Microsoft.XMLHTTP");
else if (window.XMLHttpRequest)
xhr = new XMLHttpRequest();
else
alert("not supported");
//prepare the xmlhttprequest object
xhr.open("GET",document.rssform.rssurl.value,true);
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Pragma", "no-cache");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4)
{
if (xhr.status == 200)
{
if (xhr.responseText != null)
processRSS(xhr.responseXML);
else
{
alert("Failed to receive RSS file from the server - file not found.");
return false;
}
}
else
alert("Error code " + xhr.status + " received: " + xhr.statusText);
}
}
//send the request
xhr.send(null);
}
//processes the received rss xml
function processRSS(rssxml)
{
RSS = new RSS2Channel(rssxml);
showRSS(RSS);
}
//shows the RSS content in the browser
function showRSS(RSS)
{
//default values for html tags used
var imageTag = "<img id='chan_image'";
var startItemTag = "<div id='item'>";
var startTitle = "<div id='item_title'>";
var startLink = "<div id='item_link'>";
var startDescription = "<div id='item_description'>";
var endTag = "</div>";
//populate channel data
var properties = new Array("title","link","description","pubDate","copyright");
for (var i=0; i<properties.length; i++)
{
eval("document.getElementById('chan_"+properties[i]+"').innerHTML = ''");
curProp = eval("RSS."+properties[i]);
if (curProp != null)
eval("document.getElementById('chan_"+properties[i]+"').innerHTML = curProp");
}
//show the image
document.getElementById("chan_image_link").innerHTML = "";
if (RSS.image.src != null)
{
document.getElementById("chan_image_link").href = RSS.image.link;
document.getElementById("chan_image_link").innerHTML = imageTag
+" alt='"+RSS.image.description
+"' width='"+RSS.image.width
+"' height='"+RSS.image.height
+"' src='"+RSS.image.url
+"' "+"/>";
}
//populate the items
document.getElementById("chan_items").innerHTML = "";
for (var i=0; i<RSS.items.length; i++)
{
item_html = startItemTag;
item_html += (RSS.items[i].title == null) ? "" : startTitle + RSS.items[i].title + endTag;
item_html += (RSS.items[i].link == null) ? "" : startLink + RSS.items[i].link + endTag;
item_html += (RSS.items[i].description == null) ? "" : startDescription + RSS.items[i].description + endTag;
item_html += endTag;
document.getElementById("chan_items").innerHTML += item_html;
}
//we're done
//document.getElementById("chan").style.visibility = "visible";
return true;
}
var xhr;
<!-- html file -->
<html>
<head>
<script language="javascript" src="rssajax.js"></script>
<style type="text/css">
#chan_items { margin: 20px; }
#chan_items #item { margin-bottom: 10px; }
#chan_items #item #item_title {
font-weight: bold;
}
</style>
</head>
<body onload="getRSS()">
<form name="rssform">
<input name="rssurl" type="hidden" value="ChapRSS.xml">
</form>
<script language="javascript" src="rssajax.js"></script>
<div class="rss" id="chan">
<div id="chan_title"></div>
<a href="chan_link" target="_blank" id="chan_link"></a>
<div id="chan_description"></div>
<div id="chan_image_link"></div>
<a href="chan_image_link" target="_blank" id="chan_items"></a>
<div id="chan_pubDate"></div>
<div id="chan_copyright"></div>
</div>
</body>
</html>
答案 0 :(得分:1)
<link>http://www.cnn.com/...?eref=rss_world&utm_source=...</link>
这不是格式良好的XML,因此也不是RSS。您必须将所有文字&符号转义为&
。
(它在HTML中无效。当您在&
属性中添加href="..."
时,您还必须将其转义为&
。区别在于浏览器通常会为您纠正错误什么时候可以; XML解析器不会。)
document.rssform.rssurl.value
在<input>
上添加ID并使用document.getElementById
与旧式表单集合访问相比不那么模糊。无论哪种方式,这是一种将价值纳入脚本的相当迂回的方式。为什么不丢失表单并简单地将RSS文件名作为参数传递给getRSS()
?
this.title;
根本没有做任何事情。你提到这样的房产没有任何地方有任何影响;你不是通过这样做来创造成员的。
var properties = new Array("title", "link", ...
通常避免使用new Array
构造函数。数组文字语法(var properties= ['title', 'link, ...];
更容易阅读,并且没有构造函数对单个参数的意外行为。
eval("this."+properties[i]+"=tmpElement.childNodes[0].nodeValue");
eval
是邪恶的。永远不要使用它。
您可以使用方括号表示法来访问具有动态名称的属性。 a.b
与a['b']
相同,因此:
this[properties[i]]= tmpElement.childNodes[0].nodeValue;
...
imgAttribs = new Array("url","title", ...
你还没有声明var imgAttribs
,这是一个意外的全球性。与Item
中的RSS2Channel
相同。 (为什么是大写字母?)
eval("this."+imgAttribs[i]+"=imgElement.getAttribute("+imgAttribs[i]+")");
由于属性名称缺少引号,这将无效。您将获得getAttribute(url)
,并且没有名为url
的变量 - &gt;错误。同样,使用方括号属性访问来设置属性而不是eval
。
eval("document.getElementById('chan_"+properties[i]+"').innerHTML = ''");
getElementById('chan_'+properties[i])
很好,在eval
中这样做是没有意义的。
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Pragma", "no-cache");
Cache-Control
和Pragma
通常是HTTP响应字段。它们不会在HTTP请求中产生您期望的效果。如果要确保客户端不发生缓存,请使用“cachebuster”方法,例如向URL的查询字符串添加随机数或时间戳。
innerHTML = curProp
危险。您提取的值是任意文本字符串,可能包含HTML特殊字符,如<
和&
。如果你将这样的字符串写入元素的innerHTML
,你可能会得到破碎的结果,如果它们包含第三方内容,你就会给自己一个跨站点脚本的安全漏洞。
您可以使用textContent=...
来设置元素的内容,而不必担心HTML转义,但是您需要检测它是否受支持并回退到IE的非标准innerText
属性如果不是。适用于所有浏览器的方法是document.createTextNode(curProp)
并将该文本节点附加到元素。
innerHTML= imageTag+" alt='"+RSS.image.description+ ...
你有完全相同的HTML转义问题:例如。描述中包含<script>
,您遇到了麻烦。您可以编写HTML编码器,例如:
function encodeHTML(s) {
return s.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"').replace(/'/g, ''');
}
innerHTML= imageTag+' alt="'+encodeHTML(RSS.image.description)+ ...
但实际上,从字符串中创建HTML完全糟透了。改为使用DOM方法:
var img= document.createElement('img');
img.src= RSS.image.url;
img.title= RSS.image.description;
img.width= RSS.image.width;
img.height= RSS.image.height;
document.getElementById('chan_image_link').appendChild(img);