///
このメモのブックマークレットはうごかなくなりました。
新しいバージョンのメモはこちら
「URLに対するフェイスブックのいいね数を調べるツール。その3」
///
どうも。kaminalyです。
以前、「URLに対するフェイスブックのいいね数を調べるツール。」
をメモったんですが、
それを改良したので、またメモっていますよ。
ブックマークレットの意味がよくわからず、
このツールを堪能できていない人も多いようですね。。。
このツールは「いいねどんだけ〜」のリンク部分を右クリックしてブックマークに保存したり、
ブックマークバーにリンクをドラックしてブックマークしたりしておいて、
いいね数を調べたいサイトをブラウザで開いた状態で、
保存しておいたブックマークを押す(開く)とアラートでお知らせするというものです。
ではどうぞ。
こちらは、@hidekiyさんのプロキシと
海外のシェアカウントサービスのsharedcount.comと
@dankogaiさんのxhrの実装をマッシュアップして作りました。
せっかくjQurey.ajaxからxhrにしたのに、IEでの挙動があやしいので、
ChromeやFirefoxなどで使うのをお勧めします。
アラートにerrorと出ることがありますが、
ページの取得に失敗したときに出るものです。
何度試してもerrorになる場合は・・・あきらめてください(汗
興味ある人は続きの開発メモもご覧下さい。
以前のやつは、いいねのトータルの数値で、
本当はshereとlikeとコメントに分けられるみたいなので、
詳細な情報に分けるというのと、ツイッターとググタスとはてブを追加しようと思って、
作業に取りかかりました。
実装はさらっと終わりました。
こんな感じ。
//bookmarklet javascript:( function(){ var s=document.createElement('script'); s.type='text/javascript'; s.onload=b; s.src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'; document.body.appendChild(s); function b(){ var $=jQuery.noConflict(true),u=encodeURIComponent(location.href); //facebook $.get('https://api.facebook.com/method/fql.query?query=select%20like_count,%20share_count,%20total_count%20from%20link_stat%20where%20url%3D%22'+u+'%22', function(d){ var fl = $(d).find('like_count').text(), fs = $(d).find('share_count').text(), ft = $(d).find('total_count').text(), fc = ft - fl - fs; //twitter $.get('http://cdn.api.twitter.com/1/urls/count.json?url='+u, function(d){ var tt = d.count; //google+ $.get('https://plusone.google.com/u/0/_/+1/fastbutton?count=true&url='+u, function(d){ var gp = $(d).find('#aggregateCount').text(); //はてブ $.get('http://api.b.st-hatena.com/entry.count?url='+u, function(d){ var hb = d == '' ? 0 : d; alert('Facebook\n-Like: ' + fl + '\n-Share: ' + fs + '\n-Comment: ' + fc + '\n-Total: ' + ft + '\nTwitter\n-Tweet: ' + tt + '\nGoogle+\n-+1: ' + gp + '\nHatena\n-bookmark: ' + hb); }); }); }); }); } } )();
で、テストしてみると・・・
エラー。
ほにゃ?
よくよく考えてみたら、クロスドメインじゃね?
なんで、Facebookだけの時は上手く動いたんだろ?
で、調べるとすぐに、
ヘッダ情報のAccess-Control-Allow-Originの存在を知ることになりました。
この情報の値を、許可するホスト名か、*にしてあげると、
XMLHttpRequest Level 2からクロスドメインでajaxできるそうです。
その際、IEでは独自実装のXDomainRequestを使えば
IE8以降で同じくクロスドメインでajaxできるそうです。
なるほど。
ヘッダ情報を追加するためのプロキシはphpなりなんなりですぐに用意できます。
例えば、
<?php //cross domain ajax proxy header("Access-Control-Allow-Origin: *"); //今回はPOST, OPTIONSは必要ないけどテンプレート的に付けている。OPTIONSはfirefox対策 header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); //IE8 fix header("Access-Control-Allow-Headers: *"); //適宜 header("Content-Type: text/plain; charset=UTF-8"); //どこかしらのurlからデータをゲットしてそのまま出力 if($_GET["url"]){ $url = rawurlencode($_GET["url"]); $facebook = file_get_contents("https://api.facebook.com/method/fql.query?query=select%20like_count,%20share_count,%20total_count%20from%20link_stat%20where%20url%3D%22".$url."%22"); $twitter = file_get_contents("http://cdn.api.twitter.com/1/urls/count.json?url=".$url); $google = file_get_contents("https://plusone.google.com/u/0/_/+1/fastbutton?count=true&url=".$url); $hatena = file_get_contents("http://api.b.st-hatena.com/entry.count?url=".$url); } print <<<__HD__ <data> {$facebook} <twitter>{$twitter}</twitter> {$google} <hatena>{$hatena}</hatena> </data> __HD__;
上記のプロキシを使うなら、こんなjsを用意すれば動く。
「プロキシのURL」は設置した場所に書き換える。
IE対策のためにjQuery.ajaxからxhrに実装をかえてあります。
//bookmarklet javascript:( function(){ var s=document.createElement('script'); s.type='text/javascript'; s.onload=b; s.src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'; document.body.appendChild(s); function b(){ var $=jQuery.noConflict(true), u='プロキシのURL.php?url='+encodeURIComponent(location.href), c=function(d){ var jq = $(d), fl = jq.find('like_count').text(), fs = jq.find('share_count').text(), ft = jq.find('total_count').text(), fc = ft - fl - fs, tt = eval('(' + jq.find('twitter').text() + '.count)'), gp = jq.find('#aggregateCount').text(), hb = jq.find('hatena').text(); hb = hb == '' ? 0 : hb; alert('Facebook\n Like: ' + fl + '\n Share: ' + fs + '\n Comment: ' + fc + '\n Total: ' + ft + '\n\nTwitter\n Tweet: ' + tt + '\n\nGoogle+\n +1: ' + gp + '\n\nHatena\n bookmark: ' + hb); }, x; if (window.XDomainRequest){ u.replace('https', 'http'); x = new XDomainRequest(); x.onload = function(){ c(x.responseText); }; x.open('GET', u); }else{ x = new XMLHttpRequest(); x.onreadystatechange = function(){ if (x.readyState === 4) c(x.responseText); }; x.open('GET', u, true); } x.send(); } } )();
とここまで進んだところで、
設置するSSLないな。。。(本当はあるんだけど、サーバ共有でなんかハズい)
httpsに置いておかないと、https付きのサイトで使えない。
むむむ。
ボロボロの精神状態でウェブを彷徨っていると、
allow-any-origin.appspot.comにたどり着いた。
これは!上記のヘッダ情報を付けてくれるプロキシ!しかもSSLに対応!
神、神が現れたのか?
書き換えたのがこちら。
IEのXDomainRequestがhttpsだと上手く動かない。
しらべると、httpでないとダメっぽい。
httpのサイトだったらhttp、httpsのサイトだったらhttpsに合わせるというような
記事も見かけてやってみたけどダメだった。
この時点で、IEではIE8以降でなおかつhttpのサイトでしか動きません。になる。
//bookmarklet javascript:( function(){ var s=document.createElement('script'); s.type='text/javascript'; s.onload=b; s.src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'; document.body.appendChild(s); function b(){ var $=jQuery.noConflict(true), u=encodeURIComponent(location.href), p='http'+(window.XDomainRequest && u.substr(0,5) != 'https' ? '' : 's' )+'://allow-any-origin.appspot.com/'; //facebook xhr(p+'https://api.facebook.com/method/fql.query?query=select%20like_count,%20share_count,%20total_count%20from%20link_stat%20where%20url%3D%22'+u+'%22', function(d){ var jq = $(d); fl = jq.find('like_count').text(), fs = jq.find('share_count').text(), ft = jq.find('total_count').text(), fc = ft - fl - fs; //twitter xhr(p+'http://cdn.api.twitter.com/1/urls/count.json?url='+u, function(d){ var tt = eval('(' + d + '.count)'); //google+ xhr(p+'https://plusone.google.com/u/0/_/+1/fastbutton?count=true&url='+u, function(d){ var gp = $(d).find('#aggregateCount').text(); //はてブ xhr(p+'http://api.b.st-hatena.com/entry.count?url='+u, function(d){ var hb = d == '' ? 0 : d; alert('Facebook\n Like: ' + fl + '\n Share: ' + fs + '\n Comment: ' + fc + '\n Total: ' + ft + '\n\nTwitter\n Tweet: ' + tt + '\n\nGoogle+\n +1: ' + gp + '\n\nHatena\n bookmark: ' + hb); }); }); }); }); function xhr(u,c){ var x; if (window.XDomainRequest){ x = new XDomainRequest(); x.onload = function(){ c(x.responseText); }; x.open('GET', u); }else{ x = new XMLHttpRequest(); x.onreadystatechange = function(){ if (x.readyState === 4) c(x.responseText); }; x.open('GET', u, true); } x.send(); } } } )();
Ver1はIE全く動かなかった(チェックすらしてなかった汗)から、
今回はIEも対応しようと思っていたのに残念な空気がながれだす。
1回調べるのにプロキシに4回もリクエストするのもなんか申し訳なくなってきた。
で、いいねの情報を分割できる事を知ったサービスでもある、
sharedcount.comからデータをパクってとマッシュアップしよう。
そうしよう。
最終的なソースはこちら。
sharedcount.comからのデータを整形したのと、
はてブがなかったので足したのと、
ロードが長くなってしまったので、「Now Loading...」の表示を足した。
あと、403エラーが出る事があったので、errorアラートを出すようにした。
//bookmarklet javascript:( function(){ var s=document.createElement('script'); s.type='text/javascript'; s.onload=b; s.src='https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'; document.body.appendChild(s); function b(){ var $=jQuery.noConflict(true), u=encodeURIComponent(location.href), p='http'+(window.XDomainRequest && u.substr(0,5) != 'https' ? '' : 's' )+'://allow-any-origin.appspot.com/', l=$(' Now Loading... ').css({position:'absolute',zIndex:10000,textAlign:'center',fontSize:'20px',backgroundColor:'#990',color:'#fff',margin:'0',padding:'30px 0',width:'100%',top:$('body').scrollTop()+'px'}).prependTo('body'); //sharedcount.com xhr(p+'http://sharedcount.com/?url='+u, function(d){ var s = $(d).find('#stats').html().replace(/\n/g,'').replace(/<!--([^>]|[^-][^-]>)*-->/g,'').replace(/<\/?h3>/g,'\n').replace(/<br[^>]*>/g,'\n'); //はてブ xhr(p+'http://api.b.st-hatena.com/entry.count?url='+u, function(d){ var h = d == '' ? 0 : d; l.remove(); alert(s + '\nHatena\nbookmarks: ' + h); }); }); function xhr(u,c){ var x; if (window.XDomainRequest){ x = new XDomainRequest(); x.onload = function(){ c(x.responseText); }; x.onerror = function(){ l.remove(); alert('error'); }; x.open('GET', u); }else{ x = new XMLHttpRequest(); x.onreadystatechange = function(){ if (x.readyState === 4){ if(x.status == 200){ c(x.responseText); }else{ l.remove(); alert('error'); } } }; x.open('GET', u, true); } x.send(); } } } )();
かなり遠回りをして、
最終的に完全に他力本願ツールになってしまった。
IE8以降でhttpは対応のはずだったんだけど、IE8でなぜか動かなかった。
もしかしたら、IE8fixのヘッダが入ってないのかも。
まぁ、IEは非対応と言い切ってしまったほうが安全なのである。