首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

C# WebBrowser 控制項綜合應用指南:本地頁面載入、JS 互通與跨域資料交換

     編輯:更多程式設計知識

WebBrowser 控制項是 WinForms 嵌入瀏覽器功能的經典方案,支援載入本地/遠端 HTML、C# 與 JavaScript 雙向呼叫、DOM 操作等。本文系統梳理核心用法、資料交換模式與常見坑點。

一、基礎配置與本地頁面載入

1. 表單載入初始化

private void Form1_Load(object sender, EventArgs e)
{
    // 使用相對路徑載入本地 HTML,確保專案可移植性
    // HTML 檔案放置於 bin/Debug/ 目錄下,VS 可直接編輯預覽
    webBrowser1.Navigate(Application.StartupPath + "/map.html");
    
    // 關鍵:暴露 C# 物件給 JavaScript 呼叫
    webBrowser1.ObjectForScripting = this;
}
路徑最佳實踐:絕對避免硬編碼絕對路徑。Application.StartupPath 指向執行檔目錄,配合「複製到輸出目錄」屬性設為「有更新時複製」,實現開發/部署環境無縫切換。

WebBrowser 載入百度地圖 API 效果圖

二、C# 呼叫 JavaScript(C# → JS)

// 呼叫無參 JS 函數
object result = webBrowser1.Document.InvokeScript("jsFunctionName");

// 呼叫帶參 JS 函數
object result = webBrowser1.Document.InvokeScript("jsFunctionWithArgs", new object[] { arg1, arg2 });

// 處理回傳值(JS 返回物件在 C# 中為 COM 物件,需轉型)
if (result != null)
{
    string jsonStr = result.ToString(); // 或 Convert.ToInt32、double 等
}

三、JavaScript 呼叫 C#(JS → C#)

1. C# 類別標記 [ComVisible(true)]

[ComVisible(true)]
public class ScriptBridge
{
    private Form1 _form;
    public ScriptBridge(Form1 form) { _form = form; }
    
    // 供 JS 呼叫的公共方法
    public void OnDistanceMeasured(double distance)
    {
        _form.UpdateDistanceUI(distance);
    }
    
    public string GetConfigValue(string key)
    {
        return ConfigurationManager.AppSettings[key];
    }
}

2. 註冊橋接物件

webBrowser1.ObjectForScripting = new ScriptBridge(this);

3. JavaScript 呼叫範例

// HTML/JS 端
function notifyDistance(distance) {
    // window.external 對應 C# ObjectForScripting 物件
    window.external.OnDistanceMeasured(distance);
}

四、實戰案例:百度地圖測距資料回傳

HTML/JS 端(map.html 片段)

<script>
// 百度地圖測距工具事件監聽
myDis.addEventListener("drawend", function(e) {
    var distance = e.distance;        // 獲取測距結果(米)
    alert("測距結果:" + distance);   // 調試用
    
    // 關鍵:主動推送給 C#
    if (window.external && window.external.OnDistanceMeasured) {
        window.external.OnDistanceMeasured(distance);
    }
});

// 供 C# 主動拉取的備用介面
function getDistance() {
    return lastMeasuredDistance;      // 全域變數緩存最近測距值
}
</script>

C# 端處理

// 方式一:被動接收推送(ScriptBridge.OnDistanceMeasured)
public void UpdateDistanceUI(double distance)
{
    if (InvokeRequired)
    {
        Invoke(new Action<double>(UpdateDistanceUI), distance);
        return;
    }
    lblDistance.Text = $"測距:{distance:F2} 米";
    _lastDistance = distance;
}

// 方式二:主動拉取(按鈕點擊等觸發)
private void btnGetDistance_Click(object sender, EventArgs e)
{
    // 注意:InvokeScript 返回 object,JS 物件/陣列會序列化為字串
    var result = webBrowser1.Document.InvokeScript("getDistance");
    if (result != null)
    {
        double distance = Convert.ToDouble(result);
        UpdateDistanceUI(distance);
    }
}

五、型別轉換與資料序列化對照表

JavaScript 型別C# 接收型別轉換建議
number (int/float)object → double/decimalConvert.ToDouble(obj)
stringobject → stringobj.ToString()
booleanobject → boolConvert.ToBoolean(obj)
Array / Objectobject → string (JSON)JS 端 JSON.stringify(),C# 端 JsonConvert.DeserializeObject
null / undefinednull / DBNull判斷 obj == null || obj is DBNull

六、常見坑點與解決方案

  1. 腳本錯誤彈窗:設定 webBrowser1.ScriptErrorsSuppressed = true 隱藏預設錯誤對話框。
  2. IE 相容模式導致 CSS/JS 失效:註冊表強制指定渲染引擎版本(需管理員權限):
    HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
    "YourApp.exe" = 11001 (IE11 Edge 模式)
  3. 跨域存取拒絕:本地檔案載入遠端資源觸發跨域,解決:HTML 端添加 <meta http-equiv="X-UA-Compatible" content="IE=Edge">,或部署至本地 HTTP 伺服器(如 https://localhost/)。
  4. 記憶體洩漏:長時間運行需定期 webBrowser1.Dispose() 重建,或遷移至 WebView2 (Chromium 內核)。

七、技術選型建議

新專案:優先選擇 WebView2 (Microsoft Edge Chromium),現代 Web 標準支援完整、效能優異、支援 ES6+、無 IE 相容包袱。
維護舊專案:WebBrowser 仍可用,但需做好上述相容性配置,並規劃遷移路線圖。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved