jFeed : jQueryプラグインでRSSやATOMを読み込み・解析・出力
2011/01/21
jQueryでRSSやATOMを簡単に扱えるプラグイン、jFeed。
それ自体は簡単なんですが、周辺で色々と問題があったので記しておきます。
jQuery: The Write Less, Do More, JavaScript Library
http://jquery.com/
jFeed: JavaScript jQuery RSS/ATOM feed parser plugin – jf-hovinne.blog
http://www.hovinne.com/blog/index.php/2007/07/15/132-jfeed-jquery-rss-atom-feed-parser-plugin
0.jFeedの設定・使用方法
a.headにパスを通す。
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery.jfeed.js"></script>
b.JSを用意、下記ソースではページ読込終了後にアラートがでます。
$(document).ready(function(){ jQuery.getFeed({ url: 'rss.xml', success: function(feed) { alert(feed.title); } }); });
c.プロパティはこんな感じ
JFeed properties: feed.type feed.version feed.title feed.link feed.description feed.language feed.updated feed.items: an array of JFeedItem JFeedItem properties: item[n].title item[n].link item[n].description item[n].updated item[n].id
1.大前提としてJavaScriptでは外部サイトのXML(RSSやATOMもXML形式の一つ)にアクセスできません。
いきなり目の前が真っ暗になりますね、だいたいRSSなんて外部のものを読み込んで、どうにかしたいのがほとんどですから。
そんな時のためにjFeedではproxy.phpが用意されていますので、proxy.php?url=外部RSSのURL等と指定すればproxy.phpが外部RSSをそのまま出力してくれますので解決。
問題はPHPが使えない時、某サイトでは同じプログラムをaspxとかで(拡張子が違うだけで、実はphpかもしれません)作ってました。プログラムが動かせない場合は、きっぱり諦めてJSONでパブリッシュしてもらうなど、他の方法を考えましょう、時間の無駄です。
2.Internet Explolerではproxy.phpを介さないで、直にXMLを指定してもXMLとして読み込まれない。(ローカル、あるいはサーバの設定によって)
IEではXMLをtext/xmlではなくプレーンテキストとして受信するようです。proxy.phpを間に入れれば解決するのですが、直にXMLを叩きたい場合は以下を参考にしてください。
Specifying the Data Type for AJAX Requests – jQuery JavaScript Library
http://docs.jquery.com/Specifying_the_Data_Type_for_AJAX_Requests
iFeedに上記を埋め込む場合は
a.iFeedはミニマム化されていない jquery.jfeed.js を読込み、これを修正します。
#わかる人は分割されているsrcでもOK←そんな人はこのエントリを読んでないと思いますが。
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery.jfeed.js"></script>
or
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jfeed.js"></script> <script type="text/javascript" src="jfeeditem.js"></script> <script type="text/javascript" src="jrss.js"></script>
b.jfeed.jsの$.ajaxを以下のように書き換えます。
$.ajax({ type: 'GET', url: options.url, data: options.data, dataType: 'xml', success: function(xml) { var feed = new JFeed(xml); if(jQuery.isFunction(options.success)) options.success(feed); } });
↓
$.ajax({ type: 'GET', url: options.url, data: options.data, dataType: ($.browser.msie) ? "text" : "xml", success: function(data) { var xml; if (typeof data == "string") { xml = new ActiveXObject("Microsoft.XMLDOM"); xml.async = false; xml.loadXML(data); } else { xml = data; } var feed = new JFeed(xml); if(jQuery.isFunction(options.success)) options.success(feed); } });
3.FireFoxだとXMLの相対指定../がうまくいかない
webサーバにあげれば大丈夫なので目をつぶります。
4.categoryとかもパースさせたい
2.の手順でソースを読み込み、各JSの該当箇所を追記します。
jFeed pluginで遊んでみた
http://www.markdiary.com/archives/2010/03-28075555.php
<category>と、<headline url=””>を追加したい場合、jquery.jfeed.js の下記を変更します。(文末の,の有無に注意!)
jQuery.getFeed = function(options) { options = jQuery.extend({ url: null, data: null, success: null }, options); if(options.url) { $.ajax({ type: 'GET', url: options.url, data: options.data, dataType: 'xml', success: function(xml) { var feed = new JFeed(xml); if(jQuery.isFunction(options.success)) options.success(feed); } }); } }; function JFeed(xml) { if(xml) this.parse(xml); }; JFeed.prototype = { type: '', version: '', title: '', link: '', description: '', parse: function(xml) { if(jQuery('channel', xml).length == 1) { this.type = 'rss'; var feedClass = new JRss(xml); } else if(jQuery('feed', xml).length == 1) { this.type = 'atom'; var feedClass = new JAtom(xml); } if(feedClass) jQuery.extend(this, feedClass); } }; function JFeedItem() {}; JFeedItem.prototype = { title: '', link: '', description: '', updated: '', id: '', category: '', headline_url: '' }; function JAtom(xml) { this._parse(xml); }; JAtom.prototype = { _parse: function(xml) { var channel = jQuery('feed', xml).eq(0); this.version = '1.0'; this.title = jQuery(channel).find('title:first').text(); this.link = jQuery(channel).find('link:first').attr('href'); this.description = jQuery(channel).find('subtitle:first').text(); this.language = jQuery(channel).attr('xml:lang'); this.updated = jQuery(channel).find('updated:first').text(); this.items = new Array(); var feed = this; jQuery('entry', xml).each( function() { var item = new JFeedItem(); item.title = jQuery(this).find('title').eq(0).text(); item.link = jQuery(this).find('link').eq(0).attr('href'); item.description = jQuery(this).find('content').eq(0).text(); item.updated = jQuery(this).find('updated').eq(0).text(); item.id = jQuery(this).find('id').eq(0).text(); item.category = jQuery(this).find('category').eq(0).text(); item.headline_url = jQuery(this).find('headline').eq(0).attr('url'); feed.items.push(item); }); } }; function JRss(xml) { this._parse(xml); }; JRss.prototype = { _parse: function(xml) { if(jQuery('rss', xml).length == 0) this.version = '1.0'; else this.version = jQuery('rss', xml).eq(0).attr('version'); var channel = jQuery('channel', xml).eq(0); this.title = jQuery(channel).find('title:first').text(); this.link = jQuery(channel).find('link:first').text(); this.description = jQuery(channel).find('description:first').text(); this.language = jQuery(channel).find('language:first').text(); this.updated = jQuery(channel).find('lastBuildDate:first').text(); this.items = new Array(); var feed = this; jQuery('item', xml).each( function() { var item = new JFeedItem(); item.title = jQuery(this).find('title').eq(0).text(); item.link = jQuery(this).find('link').eq(0).text(); item.description = jQuery(this).find('description').eq(0).text(); item.updated = jQuery(this).find('pubDate').eq(0).text(); item.id = jQuery(this).find('guid').eq(0).text(); item.category = jQuery(this).find('category').eq(0).text(); item.headline_url = jQuery(this).find('headline').eq(0).attr('url'); feed.items.push(item); }); } };
ここまで