Xilium CefGlue 關于瀏覽器開發,注冊JavaScript文件,并解決中文亂碼

作者: 時間: 2014-02-23 分類: 技術文章 | 3 評論數 |

技術要求:需要對基于cef3瀏覽器開發有一定了解,了解瀏覽器運行過程中,對各模塊的調用過程。

應用場景:自定義瀏覽器,添加自己的js函數庫。本文由群友“汪博”編寫,非常感謝!

轉載注明“吾樂吧軟件站”,原文鏈接:http://www.pllkp.tw/?p=24795

感興趣的,可以加入:WebKit/Blink 內核瀏覽器開發 QQ交流群:244840771

開發語言為:.NET/C++ 方向

實現過程:

1、 準備js文件,js文件中的函數可以先用chrome瀏覽器測試。本例中創建test.js的腳本文件,文件中腳本內容如下。

?C# Code?By WuleBa.COM
1
2
3
4
5
6
7
function?MyExtFunctions(){?}
if?(!MyExtFunctions)MyExtFunctions?=?{};
(function(){
MyExtFunctions.getinfo?=?function()?{
alert(
‘中文行不行test.js?fileload哈哈呵呵’);
};
})();

2、 添加繼承于CefRenderProcessHandler的類,這里叫MyCefRenderProcessHandler,重寫OnWebKitInitialized方法,在OnWebKitInitialized方法中添加注冊js腳本文件的代碼,示例如下。

?C# Code?By WuleBa.COM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
protected?override?void?OnWebKitInitialized()
{
string?dir?=?“MyJSFilePath”;
string?path?=System.IO.Path.GetDirectoryName(newUri(System.Reflection.Assembly.GetEntryAssembly().CodeBase).LocalPath);
string?fullpath?=?path?+“\\”?+?dir;

if?(Directory.Exists(fullpath))
{
string[]?files?=Directory.GetFiles(fullpath);

foreach?(string?item?in?files)
{
FileInfo?fi?=?newFileInfo(item);
StreamReader?objReader?=
new?StreamReader(fi.OpenRead(),?Encoding.UTF8);
string?javascriptCode?=objReader.ReadToEnd();
objReader.Close();

CefRuntime.RegisterExtension(fi.Name,?javascriptCode,?null);
}
}
else
{
MessageBox.Show(
“JS文件路徑不存在”);
}

base.OnWebKitInitialized();
}

3、 這樣瀏覽器啟動的時候,就會自動加載js文件,我們可以在html文件這樣調用。

?C# Code?By WuleBa.COM
1
2
3
functionButton2_onclick()?{
MyExtFunctions.getinfo();
}

4、 打開瀏覽器調用到這個自定義函數后,彈出提示框,會發現中文變成了亂碼,于是嘗試改變讀取文件的編碼格式,以及js腳本文件本身保存的編碼格式。

StreamReader(fi.OpenRead(), Encoding.UTF8);這里嘗試各種編碼都無效。

5、 結果反向跟著CefRuntime.RegisterExtension方法,查看源代碼,發現varn_javascriptCode = new cef_string_t(javascriptCode_str, javascriptCode.Length);這里會將文件讀取的js腳本轉換成cef_string_t,然后繼續跟蹤,發現cef_string_t重寫的tostring方法中,returnnew string((char*)obj->_str, 0, (int)obj->_length);這個還原的過程出了問題,發現對中文的解析,出現了問題,utf8中一個中文三個字節,指針中的char類型是單字節的,而c#中卻不是,輸出轉換結果會發現,char*轉成c#中的char值時不對的,有時候是負數,所以使用c#提供的默認轉換機制是有問題的,這里就需要我們自己來寫代碼轉換,如下。

?C# Code?By WuleBa.COM
1
2
3
4
5
Listlist?=?new?List();
int?len?=(int)obj->_length;
list.Add(*((
byte*)(obj->_str+?i)));
string?ret?=?System.Text.Encoding.UTF8.GetString(list.ToArray());
return?ret;

6、 這回我們在瀏覽器中調用MyExtFunctions.getinfo();函數時就能正常顯示中文了。到目前為止看似正常了,但是還有一個隱患。

7、 如果我們再瀏覽器中還需要做一些擴展,需要一個js函數MyExtFunctions.getinfo(obj);這個函數實現也是通過CefRuntime.RegisterExtension來注冊,代碼如下。

?C# Code?By WuleBa.COM
1
2
3
4
5
6
7
8
9
[email protected]“function?MyExtFunction()?{}
if?(!MyExtFunction)?MyExtFunction?={};
(function()?{
MyExtFunction.browserFunction?=function(mes)?{
alert(mes);
};
})();
“;

CefRuntime.RegisterExtension(“MyWindowExtensionJS”,MyWindowJavascriptCode,?null);

8、 然后,我們可以在html文件這樣調用。

?C# Code?By WuleBa.COM
1
2
3
functionButton3_onclick()?{
MyExtFunction.browserFunction?(‘test?中文title’);
}

9、 這回居然又是亂碼,原來這里的js代碼被v8獲取到后,也是要通過cef_string_t類中的tostring方法輸出,但是這里得到char*是C#中的char類型,不是單字節,通過對(char*)obj->_str中的char逐個輸出,得到結果,這里的中文都是用一個char存儲,所以這里就會得出,這里的obj->_str有兩個來源,一個是從js文件中載入,一個是瀏覽器運行后,從瀏覽器段傳入。而且編碼格式不同,需要進行識別。

10、這里我采取的辦法是,同時用兩種方式輸出tostring的結果,然后判斷其中是否含有中文的char字符,代碼如下。

?C# Code?By WuleBa.COM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Listlist?=?new?List();
Listlistc?=?newList();
int?len?=?(int)?obj?–?>?_length;
bool?bret?=?false;

for?(int?i?=?0;?i?<?len;?i++)
{
list.Add?(*?(?(
byte?*)?(obj?–?>?_str?+?i)?)?);
listc.Add?(*?(?(
char?*)?(obj?–?>?_str?+?i)?)?);

if (Convert.ToInt32(listc[i])>= 0x4e00 && Convert.ToInt32(listc[i]) <= 0x9fff)
{
bret?=?true;
}
}

string?ret?=?System.Text.Encoding.UTF8.GetString?(list.ToArray()?);
string?ret2?=?newstring?(listc.ToArray()?);

if?(bret)
{
return?ret2;
}
else
{
return?ret;
}

以上是整個解決過程,采取的辦法也是應急的辦法,沒有繼續深入去挖源代碼,不過還是解決了問題,如果有更好的方式,歡迎分享交流。

本文采用 CC協議 發布,轉載請注明:轉載自 吾樂吧軟件站

本文鏈接地址:http://www.pllkp.tw/?p=24795

3 條評論 給“Xilium CefGlue 關于瀏覽器開發,注冊JavaScript文件,并解決中文亂碼”

  1. 大牛,求解釋一下這一句代碼(最后一段代碼的12行)
    if (Convert.ToInt32 (listc[i]) > = 0x4e00 & amp; & Convert.ToInt32 (listc[i])

  2. lz你好,看了你的文章深受啟發,但目前還是卡在一個問題上沒有頭緒,就是如何為CefGlue開發擴展,或者說chrome的擴展(crx后綴的文件)是否可以直接被CefGlue使用,求lz指點?

    • 首先明確告訴你,直接把crx拿來是肯定不能用的。我也想知道怎樣開發他的擴展,目前沒找到答案。。。。。但是我之前跟進之后發現的基本方向就是:通過注冊JS,然后實現所謂的插件(簡單的是可以實現的)。至于正確的做法是否如此?暫不清楚

發表評論

?
微軟MSDN資源免費訂閱,MSDN 我告訴你 越南美女捕鱼捕走光视频 体彩20选5走势图 体彩开奖时间规则 六合彩开奖现场直播 重庆时时是不是真的 海南省高考地方专项 分分赛计划 天津怏乐十分开奖结果 河北20选5走势图连线 吉林快三精准人工计划网 男人味顶尖六肖资料77 三分赛计划 三肖中特免费资料大全 彩票万能公式 平特一肖l类公式 时时后一视频教程稳赚 tk35图库大全