百度文庫瀏覽器分析及實現 (轉自勤浪)

一、        引子
2003年開始玩Flash,完了兩年就戒掉了;長時間不用不完慢慢就生疏了。最近應客戶的需要,希望能在文檔系統中實現類似百度文庫的效果。考查一番,咋看起來百度用的是FlashPaper技術,也看了看FlexPaper,在GoogleCode上還看到了一個超大文件的示例,可惜鏈接打不開,無法去詳細分析他們了。

在能看到的應用中,FlashPaper、FlexPaper都不能達到在互聯網上動態加載大文檔的用戶體驗需求;唯獨百度文庫有這樣的用戶體驗,因此就只能拿百度文庫開刀了,希望李彥宏同志不要見怪。

姑且拿《六十八個經典小故事》作爲示例,該文檔頁數足夠多,能夠展示動態加載的效果。

二、        百度文庫瀏覽器原理分析步驟
1.      找到《六十八個經典小故事》對應的鏈接;

2.      清空IE緩存,在IE中瀏覽該頁面;

3.      使用導航將文檔瀏覽至最後;

4.      抓取IE緩存中的內容;

5.      材料已取好,分析開始。

三、        百度文庫瀏覽器代碼分析
一進來,劉姥姥進了大觀園了,這個JavaScript腳本看得人腦袋那個大啊,這條路走起來挺艱難,換個思路吧;找個Flash反編譯工具,反編譯一下,取出來ActionScript,這個好歹還有個分行短句啊,總算還是個代碼。

整理整理代碼的層次結構,按照包組織一下,大致能確認應該在baidu這個文件夾吧;再看看,lib大致是用於json處理的;ui是用於用戶自定義控件;iknow就應該是程序入口吧,按照一般程序要的思路先找一找main吧,果然還真有一個main類,有意思。

 

 

下面這幾句代碼大概就是與外部進行參數交換的吧:

 

var _loc_2:* = _loc_1["docurl"] || "http://jx-iknow-test15.jx.baidu.com:8960/play";

var _loc_3:* = _loc_1["docid"] || "c881e53a580216fc700afd05";

var _loc_4:* = int(_loc_1["fpn"]) || 2;

var _loc_5:* = int(_loc_1["npn"]) || 5;

this._reader.fpn = _loc_4;

this._reader.npn = _loc_5;

this._reader.docURL = _loc_2.replace(/(//)+$/, "") + "/" + _loc_3 + "?";

如此以來就可以查找docurl、docid、fpn、npn這幾個參數了,在JavaScript或者json中應該有體現的。

在看一看Reader類,再看看DocViewer類大致就知道了百度的FlashPaper的Reader的原理了。

if (this._firstPagesNum == -1)

{

tmpURL = this._docURL + "pn=" + (this._pagesLoaded + 1) + "&rn=" + this._normalPageNum;

}

else

{

tmpURL = this._docURL + "pn=1&rn=" + this._firstPagesNum;

this._firstPagesNum = -1;

}

var binaryRequest:* = new URLRequest(tmpURL);

binaryLoader.load(binaryRequest);

這就是Reader獲取FlashPaper資源文件了;

binaryLoader.addEventListener(ProgressEvent.PROGRESS, this.binaryLoading);

binaryLoader.addEventListener(Event.COMPLETE, this.binaryLoadComplete);

binaryLoader.addEventListener(IOErrorEvent.IO_ERROR, this.binaryLoadError);

這個就是定義的裝載進度、裝載完成、裝載失敗的幾個事件響應了;

this._delayPreLoadID = setInterval(this.preLoad, 1000, _loc_3);

這個是用於預裝載的動作,實現邊查看邊下載其他片段的。

四、        百度文庫瀏覽器參數分析
根據以上代碼片段就可以知道百度FlashPaper Reader的工作原理了,在初始化時根據JavaScript的參數裝載FlashPaper片段,使用docurl指定路徑(可以是相對路徑,可以是絕對路徑),使用docid指定文檔的GUID,fpn指定文檔起始序號,rn指定文檔片段的頁數;根據百度文檔內部的定義應該是將文檔以5頁或者10頁進行組織,所以fpn=5*X+1;rn=5||10。

五、        百度文庫瀏覽器外部調用分析
回過頭在看客戶端調用的JavaScript代碼就有針對性了,不用頭大了;先看一看html頁的代碼吧,打開“9daa5522aaea998fcc220e73.html”頁面,看一看裏面的代碼,看看有不有對應的參數,您別說還真就有,不管咋說吧,代碼有點閱讀困難,好在只定位於使用這段代碼,咱改改參數用用,其他的就不深入研究了。

function Reader(){

function B(){

if(baidu.swf.getVersion()){

return true

}else{

_id.innerHTML='<p class="ml">文檔預覽需要最新版本的Flash Player支持。</p><p class="ml">您尚未安裝或版本過低,建議您:</p><a href="http://www.baidu.com/s?ie=gb2312&bs=flash+%CF%C2%D4%D8&sr=&z=&cl=3&f=8&wd=Flash+Player+%CF%C2%D4%D8&ct=0" target="_blank"><img src="http://box.zhangmen.baidu.com/images/setupflash.gif" height="39" width="273" /></a>';

return false

}

}

this.create=function(D,C){

baidu.swf.create({

id:"reader",

width:"717",

height:"700",

ver:"9.0.0",

errorMessage:"Please download the newest flash player.",

url:"/static/flash/reader.swf",

bgColor:"#FFFFFF",

wmode:"window",

allowfullscreen:"true",

vars:{

docurl:"/play",

docid:"9daa5522aaea998fcc220e73 ",//貌似這就是id了

fpn:"5",

npn:"5"

}

},D);A(D)};

function A(C){

baidu.on(C,"mousewheel",function(D){

var F=D.wheelDelta;

var E=-3;

if(F<0){

E=3

}

baidu.swf.getMovie("reader").NS_IK_doMouseWheel(E);

baidu.preventDefault(D)

});

if(window.addEventListener){

baidu.G(C).addEventListener("DOMMouseScroll",function(D){

var F=D.detail;

var E=-3;

if(F>0){

E=3

}

baidu.swf.getMovie("reader").NS_IK_doMouseWheel(E);

baidu.preventDefault(D)},false)

}}}

var DOC_INFO={

doc_id:"9daa5522aaea998fcc220e73",

cid:"134",

price:"0",

value_average:"7"

};

var _reader=new Reader();

_reader.create("readerContainer","9daa5522aaea998fcc220e73");

baidu.each(

["selfChangeCategory","adminChangeCategory","selfChangePrice"],function(B,A){

baidu.on(B,"click",function(C){

login.check(baidu.proxy(view.changeDocInfo,B));

baidu.preventDefault(C)})});

baidu.on("addToStore","click",function(A){

window.open("http://cang.baidu.com/do/add?it="+encodeURIComponent(document.title)+"&iu="+encodeURIComponent(location.href)+"&tn=文庫&fr=wk#nw=1","_s","scrollbars=no,width=600,height=450,right=75,top=20,status=no,resizable=yes");

pop.show("提示",{

url:"/static/html/empty.html",

width:420,

height:250

});

document.AddToStore.submit();

baidu.preventDefault(A)

});

baidu.each(["downloadTop","downloadButton"],function(A){

baidu.on(A,"click",function(B){

log.send("down","download",{fr:"down"});

login.check(view.download);

baidu.preventDefault(B)

})});

var rate=new Rate("rateContainer");

rate.create("7");

if(G("kw")){G("kw").value=""};

六、        百度文庫現場取材實現
既然分析清楚了,下一步將百度文庫的文件結構整清楚,然後放入對應的內容,稍微對靜態代碼進行一些調整;部署到根目錄即可使用;

這裏面有百度對FlashPaper文檔swf的改造,暫且不說了,其實就是追加了一個json的文件頭數據塊,對咱們當前要就地取材實現而言沒有任何障礙。

文檔結構整理如下:

 

 

將文件都歸到對應的文件夾下,既然百度對FlashPaper/FlexPaper對應的swf做了改造,那好就將swf文件改名爲swfx吧。值得注意的是需要在IIS部署時增加MIME類型swfx爲application/swfx;只是遺憾的是由於swfx當前還不能接受參數,所以不能進行動態加載緩存頁面,不過沒有關係,等下次使用URL ReWrite整個處理一下,一個真實的百度FlashReader就完成了。

我們的口號是,不求讀懂百度文庫裏面的每一句代碼,但求利用已有材料。

七、        百度文庫DotNet模擬
敬請期待吧…

八、        製作自己的百度FlashPaper—swfx

未完待續…

 

從這裏下載靜態版本(未實現動態預裝載)http://download.csdn.net/source/2137831

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/chinull/archive/2010/03/17/5390830.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章