jQueryでRSSを取得する

はじめに

jQueryでAjaxを使用してRSS1.0(RDF)/RSS2.0/ATOMを取得します。

CORS対応が難しそうなので、サーバ側でPHPを使用して外部サイトのRSSを取得し、クライアントにそのまま返します。
それなら別にPHPで全部やれば!?って話ですが、jQueryのお勉強ってことで。。。

relay.php

<?php

$query = $_SERVER['QUERY_STRING'];
$url = preg_replace('/url=(.*)&_=[0-9]+$/i','$1', $query);
$xml = file_get_contents($url);
header('Content-type: application/xml');
echo $xml;

?>

PHP側では、クエリパラメータに設定されているURIを使用して外部サイトにアクセスし、RSSを取ってきます。jQueryの$.ajax({})でcache:falseに設定しているため、クエリパラメータに"&_=<Dateのシリアル値>"が付与されるので除去してしまいます。cache:trueにした場合、正規表現を、$url = preg_replace('/url=(.*)/i','$1', $query);に修正します。

チェックやエラー処理は全くしていませんが、本稿の主題ではないのでご勘弁を。

ajax.html

<!DOCTYPE html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
$.support.cors = true;

$(function() {
    var accessURI = "http://<ServerIP>|<Domain>/relay.php?url=";
    var _url = "";
    var _id  = "";
    var _num = 10;
    _url = accessURI
         + 'https://news.yahoo.co.jp/pickup/computer/rss.xml';
    _id  = "yahoo";
    readRSS(_url, _id, _num);

    _url = accessURI
         + 'http://gigazine.net/index.php?/news/rss_2.0/';
    _id  = "gigazine";
    readRSS(_url, _id, _num);

    _url = accessURI
         + 'https://rss.itmedia.co.jp/rss/1.0/topstory.xml';
    _id  = "itmedia";
    readRSS(_url, _id, _num);

    _url = accessURI
         + 'http://www.godac.jamstec.go.jp/darwin/static/xml/darwin_update_atom_j.xml';
    _id  = "darwin";
    readRSS(_url, _id, _num);

});

var readRSS = function(_url, _id, _num) { 
    $.ajax({
        url      : _url,
        async    : true,
        cache    : false,
        dataType : "xml",
    }).then(
        _xml => $('#' + _id).html(writeRSS(_xml, _num)), 
        _err => console.log(_err)
    );
}

var writeRSS = function(_xml, _num) { 
    var html = "";

    var elemStr = {};
    if ($(_xml).find('rdf\\:RDF')[0]) {
        // RSS1.0 RDF
        elemStr.root  = 'rdf\\:RDF';
        elemStr.item  = 'item';
        elemStr.title = 'title';
        elemStr.link  = 'link';
        elemStr.date  = 'dc\\:date';
        elemStr.desc  = 'description';

    } else if ($(_xml).find('channel')[0]) {
        // RSS2.0
        elemStr.root  = 'channel';
        elemStr.item  = 'item';
        elemStr.title = 'title';
        elemStr.link  = 'link';
        elemStr.date  = 'pubDate';
        elemStr.desc  = 'description';

    } else if ($(_xml).find('feed')[0]) {
        // ATOM
        elemStr.root  = 'feed';
        elemStr.item  = 'entry';
        elemStr.title = 'title';
        elemStr.link  = 'link';
        elemStr.href  = 'href';
        elemStr.date  = 'updated';
        elemStr.desc  = 'summary';
    }
    var rootElem = $(_xml).find(elemStr.root + ":first");
    var title    = $(rootElem).find(elemStr.title + ":first").text();
    var link     = $(rootElem).find(elemStr.link  + ":first").text();
    html += '<h3><a href="' + link + '" target="_blank">' + title + '</a></h3>';
    html += '<ul>'; 

    $(rootElem).find(elemStr.item).each(function(i) {
        if (i < _num) { 
            var posTitle = $(this).find(elemStr.title).text();
            var posLink  = $(this).find(elemStr.link).text();
            if (elemStr.href) {
                posLink  = $(this).find(elemStr.link).attr(elemStr.href);
            }
            var posDate  = $(this).find(elemStr.date).text();
            var posDesc  = $(this).find(elemStr.desc).text();

            html += '<li><a href="' + posLink + '" target="_blank">' + posTitle + '</a> - ' + posDate + '<br />' + posDesc + '</li>';
        }
    });
    html += '</ul>'
    return html;
}
</script>
</head>
<body>
<h1>RSS</h1>
<div id="yahoo"></div>
<div id="gigazine"></div>
<div id="itmedia"></div>
<div id="darwin"></div>
</body>
</html>

クライアント側ではrelay.phpにGETリクエストを送信します。リクエストを受けたrelay.phpはクエリパラメータに設定されているURIにアクセスしRSSを取得し結果をクライアントに返却します。

$(ajax)で取得したXMLを元にHTMLにして出力します。

$(function() {});内で定義しているパラメータは以下の通り。

  • _url : アクセス先URLにクエリパラメータurl=<URL>を付与した文字列
  • _id : DIV要素を一意に識別するID
  • _num : RSS表示件数

ll.50-77 は、取得する要素名が仕様によって違うので、RSSの仕様に合わせた要素名を定義しています。HTML生成部分をRSSの仕様毎に書きたくなかったのでこんな感じにしています。

$.ajax()でアロー演算子を使用しているため、IE11では動作しません。

_xml => $('#' + _id).html(writeRSS(_xml, _num)), 
_err => console.log(_err)

IE11の場合、上記を以下のように書き換えれば動きます(たぶん)。

function(_xml) {
    $('#' + _id).html(writeRSS(_xml, _num));
},
function(_err) {
   console.log(_err); 
}

初めてjQueryを使用してみましたが、とても便利ですね。もっと早く使ってみれば良かった。

参考リンク