Tuesday, November 3, 2009

c( ̄ܫ ̄)a 之Facebook開發手札 – Iframe與XFBML綜合測試


有稍稍讀過Facebook文件的人都知道, Facebook的應用程式開發模式主要可以分成三大類, 那就是FBML, Iframe以及Facebook Connect. 以往很多原文書都建議採用FBML的開發模式, 也許是因為透過FBML可以輕易的讀取許多Facebook上的Social Content或是書上那些簡單的範例只需要套用FBML即可. 但是自從Facebook開放可以在Iframe中使用XFBML之後, Iframe也可以輕易的利用一些fb命名空間下的特殊Tag去取用Facebook上的Social Content, 我們接下來就做個實驗吧.

 
 XFBML是三小!? 就我的認知而言就是一組由Facebook設計在fb這個命名空間下的特殊標籤, 當HTML頁面載入這些之後, 會透過一些引入的Facebook Javascript去載入相對應的HTML在這些XFBML標籤內, 如下圖所示.
2009-11-04_115241
我們可以看見, 我在以Iframe模式下開發的APP中加入<fb:profile-pic></fb:profile-pic>這一個XFBML標籤, 當我於Chrome中完成APP的載入之後, Facebook在<fb:profile-pic></fb:profile-pic>標籤內自動替我插入了一段HTML, 而那段HTML就是用來顯示我在Facebook上使用的Avatar.
知道Facebook在後頭變了什麼把戲之後, 我們來看看如何實做在Iframe開發模式中套用XFBML.
透過Facebook PHP Client Libraries取得目前登入Facebook使用者的UID
<?php
header('P3P: CP="CAO PSA OUR"');
//header('P3P: CP="HONK"');
require_once('./facebook-platform/php/facebook.php');
require_once('./facebook-platform/php/facebookapi_php5_restlib.php');

$appapikey = '{API Key}';
$appsecret = '{Secret Key}';
$facebook = new Facebook($appapikey, $appsecret, true);
$uid = $facebook->require_login();
//printf('<pre>%s</pre>',var_export($_REQUEST,true));
?>




在HTML的<head>中新增一個FB的命名空間    xmlns:fb="http://www.facebook.com/2008/fbml"


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>六葉摩卡 - Facebook PHP Client Libraries Demo - FXBML與Stream.publish綜合測試</title>
<link href="./js/jquery-ui-1.7.2/development-bundle/themes/base/ui.theme.css" rel="stylesheet" type="text/css" />
<link href="./js/jquery-ui-1.7.2/development-bundle/themes/base/ui.core.css" rel="stylesheet" type="text/css" />
<link href="./js/jquery-ui-1.7.2/development-bundle/themes/base/ui.dialog.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="./js/jquery-ui-1.7.2/js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="./js/jquery-ui-1.7.2/development-bundle/ui/ui.core.js"></script>
<script type="text/javascript" src="./js/jquery-ui-1.7.2/development-bundle/ui/ui.dialog.js"></script>
</head>


建立一個跨網域通道檔, 放置在根目錄下或是任何可以用相對路徑方式讀取到的地方


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
 <html xmlns="http://www.w3.org/1999/xhtml" > 
  <head>  
   <title>Cross-Domain Receiver Page</title> 
  </head> 
  <body>  
   <script src="http://static.ak.facebook.com/js/api_lib/v0.4/XdCommReceiver.js?2" type="text/javascript"></script> 
  </body> 
 </html>


於<body>標籤內引入下面這支js


<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>





啟動動態載入Facebook Javascript Client Libraries





$(function(){
    FB.Bootstrap.init('{輸入API Key}','xd_receiver.htm');
    FB.Bootstrap.ensureInit(function(){
    //寫在這裡的js可以確保是在動態載入的js都已經完成載入之後才被執行.            
});





最後在頁面中寫入下面的XFBML


<div style="margin:5px;">
 <fb:profile-pic uid="<?php echo $uid; ?>" facebook-logo="true" linked="false" size="square"></fb:profile-pic>
</div>
<div style="margin:5px;">
 <fb:name uid="<?php echo $uid; ?>"></fb:name>
</div>





當頁面於Chrome中完成載入之後就會呈現如下圖


六葉摩卡 - 臉書 PHP Client Libraries Demo on Facebook_1257308642496


完整程式碼


<?php
header('P3P: CP="CAO PSA OUR"');
//header('P3P: CP="HONK"');
require_once('./facebook-platform/php/facebook.php');
require_once('./facebook-platform/php/facebookapi_php5_restlib.php');

$appapikey = '{輸入你的API Key}';
$appsecret = '{輸入你的Secret Key}';
$facebook = new Facebook($appapikey, $appsecret, true);
$uid = $facebook->require_login();
//printf('<pre>%s</pre>',var_export($_REQUEST,true));
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>六葉摩卡 - Facebook PHP Client Libraries Demo - FXBML與Stream.publish綜合測試</title>
<link href="./js/jquery-ui-1.7.2/development-bundle/themes/base/ui.theme.css" rel="stylesheet" type="text/css" />
<link href="./js/jquery-ui-1.7.2/development-bundle/themes/base/ui.core.css" rel="stylesheet" type="text/css" />
<link href="./js/jquery-ui-1.7.2/development-bundle/themes/base/ui.dialog.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="./js/jquery-ui-1.7.2/js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="./js/jquery-ui-1.7.2/development-bundle/ui/ui.core.js"></script>
<script type="text/javascript" src="./js/jquery-ui-1.7.2/development-bundle/ui/ui.dialog.js"></script>
</head>
<body>
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>

<div style="margin:5px;">
 <fb:profile-pic uid="<?php echo $uid; ?>" facebook-logo="true" linked="false" size="square"></fb:profile-pic>
</div>
<div style="margin:5px;">
 <fb:name uid="<?php echo $uid; ?>"></fb:name>
</div>

<div style="display:none;margin:5px;padding:5px;border:solid 1px gray;width:50%;height:300px;overflow-x:hidden;overflow-y:auto;">
 <div style="margin:5px;">
  <fb:prompt-permission perms="read_stream">允許擴展權限 - read_stream</fb:prompt-permission> 
 </div>
 <div style="margin:5px;">
  <fb:prompt-permission perms="publish_stream">允許擴展權限 - publish_stream</fb:prompt-permission>
 </div> 
</div>

<div style="margin:5px;display:none;">
 <input type="text" id="story" style="width:400px;margin:5px;padding:5px;" />
 <input type="button" value="發送Stream測試" id="sendBtn" style="margin:5px;" />
 <input type="button" value="取得Allocation" id="getAbminAllocationBtn" style="margin:5px;" />
</div> 

<script type="text/javascript">

var LIB = {
    myGetAdminAllocation : function(){
        var sessionid = (new Date()).getTime();
        $.ajax({
            type: "POST",
            url: "./ajax/ajaxGetAdminAllocation.php",
            data: {
            'sessionid':sessionid
            },
            cache: false,
            beforeSend : function(){
            },
            success: function(json){
                alert(json);return false;
            }
        });
    }
}

$(function(){
    FB.Bootstrap.init('{輸入你的API Key}','xd_receiver.htm');
    FB.Bootstrap.ensureInit(function(){    
                
        $('#getAbminAllocationBtn').bind('click',function(){
            LIB.myGetAdminAllocation();
            return false;
        });

        $('#sendBtn').bind('click',function(){

            /*FB.Facebook.apiClient.users_hasAppPermission('publish_stream',function(r){
            if(!r){
            alert('請先向使用者申請publish_stream的擴展權限');
            return false;
            }
            });*/

            var story = $('#story').attr('value');

            if( !story ){
                alert('請輸入要發送到使用者Wall中的Story!');
                return false;
            }

            var sessionid = (new Date()).getTime();
            $.ajax({
                type: "POST",
                url: "http://www.6yeah.com/fb_apps/php_demo/ajax/openStreamAPIDemoStreamPublishHandler.php",
                data: {
                'story':story,
                'fb_sig_session_key':'<?php echo $_REQUEST['fb_sig_session_key'] ?>',
                'sessionid':sessionid
                },
                cache: false,
                beforeSend : function(){
                },
                success: function(json){
                    alert(json);return false;
                }
            });
        });
    });
});
</script>
</body>
</html>

3 comments:

  1. 寫得很棒
    我是FB developer 新手
    最近的困擾就是當用iframe時很多FBML都不能應用

    你這篇文章讓我燃起希望 之前那些iframe程式都可以再加值利用
    但因為才疏學淺 幾個問題請教
    1. 文章中所謂 "建立跨網域通道" 的意思是?另開一個檔案嗎?還是??
    2. 是不是運用這種方法,可以將iframe與FBML整合,有沒有一些不支援的fb tag,我關心的是那些 以及配合profile_setFBML和stream API等擴大分享邀請的常見功能是否支援

    無論如何謝謝您的分享

    ReplyDelete