Wednesday, November 4, 2009

c( ̄ܫ ̄)a 之Facebook開發手札 – 繼續探討FeatureLoader.js.php


稍微複習一下, 這是幹啥用的
  • 如果要在Facebook以外的網頁透過Facebook Connect與Facebook進行互動, 這是一個一定要引入的js
  • 引入這個檔案的js必須寫在<body>標籤之內.
  • 每一個Web頁面只能也只需要引用FeatureLoader.js.php一次, 如果你有引入Facebook所提供的Social Widget像是Fan BoxFb:comments (XFBML)等等, 你不用再重新引入FeatureLoader.js.php.
以下就是引入該檔案的語法, 也可以透過變更語系參數去.
<script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US"></script>

//我們可以透過變更語系參數去載入不同語系的FeatureLoader.js.php
//http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/{語系碼}





最單純的初始化


<script type="text/javascript">
$(function(){
    FB.Bootstrap.init('{API Key}','xd_receiver.htm');
    FB.Bootstrap.ensureInit(function(){
        alert('您已經成功的初始化了Facebook Connect一些必要的設定了!');
        return false;
    });
});
</script>


我個人習慣利用jQuery的$函數去確保在頁面的DOM都已經完成載入之後才繼續進行後續動作.


到目前為止, 整個Facebook Javascript Client Libries中只有FB.Bootstrap類別下的方法可以進行調用.


其中最重要的就是FB.Bootstrap.init






























































參數
型態
說明
備註
apiKey
String
Facebook APP或是進行Facebook Connect第三方網站的API Key

xdChannelUrl
String
跨網域存取頻道檔的相對路徑




跨網域溝通的
說明文件



appSettings
物件


  • reloadIfSessionStateChanged




    布林值, 如果設定為true的話, Facebook會監測目前登入使用者的Session狀態, 如果使用者的Session State發生改變, Facebook會自動reload目前的頁面.




  • ifUserConnected




    此參數可以為一個代有UID參數(未登入狀態下UID為null)的回呼函數或是URL字串. 如果傳入的參數內容是函數, 那當使用者完成與Facebook的連結之後就會引發此函數, 反之如果傳入的是URL字串, 那與Facebook完成Connect的使用者會被重導向到指定的URL. 另外, 此參數不能與reloadIfSessionStateChanged參數同時使用.




  • ifUserNotConnected




    如同ifUserConnected的運作方式, 此參數可以是一個代有UID參數(未登入狀態下UID為null)的回呼函數或是URL字串, 為一不同的是當使用者已經與Facebook失去Connect之後才會觸發回呼函數或是URL的重導向.




  • doNotUseCachedConnectState




    布林值, 預設值為false, 也就是說Facebook會檢查Cookie裡的連線狀態(Connect State). 如果設定為true的話, Facebook會清除被快取住的Cookie值並放棄使用這些被清除的Cookie.



debugLogLevel
整數型態
用來設定寫入Firebug Console除錯訊息的詳細程度.







我覺得整個FB.Bootstrap.init裡面最tricky的地方就在於appSettings這一個物件參數, 反覆讀了好幾次官方文件也都很難完全理解, 所以以下是一系列的試驗, 希望能透過實做去一一釐清各個參數的意義.


我們先來看看doNotUseCachedConnectState分別設成true與false會發生什麼事.


<script type="text/javascript">
$(function(){
    FB.Bootstrap.init('67583083bb0afbb61c3a4f9ff2daf9cf','xd_receiver.htm',
    {
        //'reloadIfSessionStateChanged':true,
        'ifUserConnected' : function(uid){
            alert('您目前已經成功與Facebook進行Connect了! - ' + uid );
            return false;
        },
        'ifUserNotConnected' : function(uid){
            alert('您目前尚未完成與Facebook的Connect! - ' + uid );
            return false;
        },
        'doNotUseCachedConnectState' : false
    });
    FB.Bootstrap.ensureInit(function(){
    });
});
</script>


如上面的程式碼所示, 我將doNotUseCachedConnectState設定成true, 如果是在登入狀態下進入測試用App話, ifUserConnected參數所帶入的回呼函數就會被觸發,頁面會出現一個彈出式視窗, 如下圖所示.


sdadasdasdasdas


反之如果是在登出Facebook的狀態下進入測試用App, ifUserNotConnected參數所代入的回呼函數就會被觸發並發出如下圖的訊息視窗.


未命名-3


接下來就有趣了, 如果我將doNotUseCachedConnectState這個布林參數改成false. 我先連入我的測試用App然後於同一個瀏覽器中開一個新的頁籤到Facebook的首頁進行登出Facebook的動作, 然後我回到我的測試用App並重新Reload頁面, 結果ifUserConnected與ifUserNotConnected這兩個設定參數所代入的回呼函數竟然都被執行到, 順序是ifUserConnected先執行然後是ifUserNotConnected. 反之如果我是在登出Facebook的狀態下進入我的測試用App, 然後於另一個頁籤進行Facebook的登入動作, 登入後我回到我的測試用App並重整頁面, 結果也是一樣, 但是執行的順序變成ifUserNotConnected先執行, 然後才是ifUserConnected. 


接下來就是我嘗試去找出這個現象的癥結的過程.


首先, 我先將登入與未登入狀態下Facebook於URL利用GET的方式傳給Iframe接收的變數分別列出來, 試著找些線索, 結果發現有如下的差別














































































































未登入狀態
已登入狀態
http://www.6yeah.com/fb_apps/php_demo/demo_1.php
http://www.6yeah.com/fb_apps/php_demo/demo_1.php


fb_sig_in_iframe=1
fb_sig_in_iframe=1
fb_sig_iframe_key=7d0665438e81d8eceb98c1e31fca80c1
fb_sig_iframe_key=7d0665438e81d8eceb98c1e31fca80c1
fb_sig_locale=en_US
fb_sig_locale=en_US
fb_sig_in_new_facebook=1
fb_sig_in_new_facebook=1
fb_sig_time=1257352753.5826
fb_sig_time=1257352832.5553
fb_sig_logged_out_facebook=1

fb_sig_added=0
fb_sig_added=1
fb_sig_api_key=67583083bb0afbb61c3a4f9ff2daf9cf
&fb_sig_api_key=
67583083bb0afbb61c3a4f9ff2daf9cf
fb_sig_app_id=184304395801
&fb_sig_app_id=184304395801
fb_sig=22cb62da13ec0bedd50767fabd56cd96
&fb_sig=
d88dc34a93f6f437e7349ed5ab9d0d6f

&fb_sig_profile_update_time=1255686889

&fb_sig_expires=1257440400

&fb_sig_user=638368594

&fb_sig_session_key=
2.L5AHQqdOCZzSm1wla7xP_w__.86400.1257440400-638368594

&fb_sig_ss=
GISOYDj_X36wsBSWlITMZw__

&fb_sig_ext_perms=
read_stream%2Cstatus_update%2C
photo_upload%2Cvideo_upload%2
Ccreate_note%2Cshare_item%2C
auto_publish_short_feed%2Cpublish_stream%2C
auto_publish_recent_activity


接下來我直接將IFrame裡的cookie直接Dump出來看看






未登入狀態下, 直接輸入APP的URL之後, 將Cookie進行dump所產生的內容


array (
  省略… 


  'fbsetting_67583083bb0afbb61c3a4f9ff2daf9cf' => '{\\"connectState\\":2,\\"oneLineStorySetting\\":3,\\"shortStorySetting\\":3,\\"inFacebook\\":true}',
)


另外開一個頁籤並進行Facebook的登入動作,回到原頁籤進行頁面的reload, 發現Cookie裡面多了些東西, 但是!!!connectState仍然是2


array (


省略…  


  'fbsetting_67583083bb0afbb61c3a4f9ff2daf9cf' => '{\\"connectState\\":2,\\"oneLineStorySetting\\":3,\\"shortStorySetting\\":3,\\"inFacebook\\":true}',
)


不死心!再重新reload一次


array (
  


省略…


'fbsetting_{API Key}' => '{\\"connectState\\":1,\\"oneLineStorySetting\\":2,\\"shortStorySetting\\":2,\\"inFacebook\\":true}',
)


Dumping出的Cookie資料中, connectState變成1了


根據這個觀察到的現象推論, 當Facebook登入後, 於APP頁面進行第一次Reload的時候, 新的connectState尚未寫進Cookie之中, 但是在頁面載入完成後可能會有一隻Javascript去檢查cookie中的connectState的值, 結果發現為2, 所以判定為尚未登入, 繼而觸發了ifUserNotConnected所設定的回呼函數. 但是接下來當Cookie被成功的重新設定為代表登入狀態的1之後, 有可能又再觸發了回呼函數ifUserConnected , 然後彈出第二個Alert視窗.


以上都只算是推論, 畢竟要Trace整個Javascript有很大的困難, 所以我是希望能在後面的研究中能查閱到相關的文件, 屆時我會再發佈出來供大家參考. 













登入Facebook之後, 將Cookie dump出來的的內容




array ( '{API Key}' => 'a6a6e0ca74a8dc84f770572804255536(這是將所有參數進行MD5雜湊後產生的fb_sig)',



'{API Key}_user' => '638368594',


'{API Key}_ss' => 'sxxCz2M9Kqrc51K2xR4lyg__',


'{API Key}_session_key' => '2.nPFypA66gvC5YARxm6fhug__.86400.1257444000-638368594',


'{API Key}_expires' => '1257444000',


'fbsetting_{API Key}' => '{\\"connectState\\":1,\\"oneLineStorySetting\\":2,\\"shortStorySetting\\":2,\\"inFacebook\\":true}',)





connectState : 初步判斷, connectState=1代表已經登入Facebook, connectState=2表示已經登出Facebook.


inFacebook : 如果為true代表APP是開啟在Facebook的Chrome之內, 反之如果為false就代表APP是位於第三方網站.












No comments:

Post a Comment