📢 FBro JavaScript对话框控制指南
完全控制网页中的JavaScript弹窗对话框,包括alert、confirm、prompt等所有类型的弹窗
📋 概述
FBro浏览器提供了强大的JavaScript对话框拦截功能,通过重写OnJSDialog方法,开发者可以完全控制网页中所有JavaScript弹窗的行为。这个功能对于自动化脚本、无人值守应用和用户体验优化非常重要。
🎯 主要功能
- 完全阻止JavaScript弹窗
- 自动处理弹窗并返回预设值
- 记录和分析弹窗内容
- 自定义弹窗响应逻辑
🔧 核心实现
OnJSDialog方法详解
csharp
/// <summary>
/// JavaScript对话框事件处理器
/// 当网页尝试显示JavaScript对话框时触发
/// </summary>
/// <param name="browser">触发对话框的浏览器实例</param>
/// <param name="origin_url">触发对话框的页面URL</param>
/// <param name="dialog_type">对话框类型(alert、confirm、prompt)</param>
/// <param name="message_text">对话框显示的消息文本</param>
/// <param name="default_prompt_text">prompt对话框的默认输入值</param>
/// <param name="callback">对话框回调接口,用于响应用户操作</param>
/// <param name="suppress_message">是否抑制消息显示</param>
/// <returns>true表示已处理该对话框,false表示使用默认处理</returns>
public override bool OnJSDialog(IFBroSharpBrowser browser,
string origin_url,
FBroJsDialogType dialog_type,
string message_text,
string default_prompt_text,
IFBroSharpJSDialogCallback callback,
ref bool suppress_message)
{
// 记录对话框信息
Console.WriteLine($"JS对话框 - 类型: {dialog_type}, URL: {origin_url}");
Console.WriteLine($"消息: {message_text}");
// 根据对话框类型执行不同的处理逻辑
switch (dialog_type)
{
case FBroJsDialogType.JSDIALOGTYPE_ALERT:
return HandleAlert(callback, message_text, origin_url);
case FBroJsDialogType.JSDIALOGTYPE_CONFIRM:
return HandleConfirm(callback, message_text, origin_url);
case FBroJsDialogType.JSDIALOGTYPE_PROMPT:
return HandlePrompt(callback, message_text, default_prompt_text, origin_url);
default:
return HandleDefault(callback);
}
}📖 参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
browser | IFBroSharpBrowser | 触发对话框的浏览器实例 |
origin_url | string | 触发对话框的页面URL |
dialog_type | FBroJsDialogType | 对话框类型枚举值 |
message_text | string | 对话框显示的消息内容 |
default_prompt_text | string | prompt对话框的默认输入值 |
callback | IFBroSharpJSDialogCallback | 对话框响应回调接口 |
suppress_message | ref bool | 是否抑制消息显示(引用参数) |
FBroJsDialogType枚举值
| 枚举值 | 说明 | JavaScript对应 |
|---|---|---|
JSDIALOGTYPE_ALERT | 警告对话框 | alert() |
JSDIALOGTYPE_CONFIRM | 确认对话框 | confirm() |
JSDIALOGTYPE_PROMPT | 输入对话框 | prompt() |
🎯 处理策略实现
1. Alert对话框处理
csharp
/// <summary>
/// 处理alert对话框
/// </summary>
/// <param name="callback">对话框回调</param>
/// <param name="message">消息内容</param>
/// <param name="url">来源URL</param>
/// <returns>是否已处理</returns>
private bool HandleAlert(IFBroSharpJSDialogCallback callback, string message, string url)
{
Console.WriteLine($"Alert对话框被拦截: {message}");
// 记录alert信息到日志
LogDialogInfo("ALERT", message, url);
// 自动确认alert对话框
callback.Continue(true, string.Empty);
return true; // 表示已处理,不显示原生对话框
}2. Confirm对话框处理
csharp
/// <summary>
/// 处理confirm对话框
/// </summary>
/// <param name="callback">对话框回调</param>
/// <param name="message">消息内容</param>
/// <param name="url">来源URL</param>
/// <returns>是否已处理</returns>
private bool HandleConfirm(IFBroSharpJSDialogCallback callback, string message, string url)
{
Console.WriteLine($"Confirm对话框被拦截: {message}");
// 根据消息内容智能判断响应
bool shouldConfirm = DetermineConfirmResponse(message, url);
LogDialogInfo("CONFIRM", message, url, shouldConfirm.ToString());
// 响应confirm对话框
callback.Continue(shouldConfirm, string.Empty);
return true;
}
/// <summary>
/// 智能判断confirm对话框的响应
/// </summary>
/// <param name="message">对话框消息</param>
/// <param name="url">来源URL</param>
/// <returns>是否确认</returns>
private bool DetermineConfirmResponse(string message, string url)
{
// 可以根据具体需求自定义判断逻辑
// 示例:包含"删除"关键词的确认框返回false
if (message.Contains("删除") || message.Contains("delete"))
{
return false;
}
// 示例:包含"保存"关键词的确认框返回true
if (message.Contains("保存") || message.Contains("save"))
{
return true;
}
// 示例:特定网站的默认处理
if (url.Contains("example.com"))
{
return true;
}
// 默认返回true
return true;
}3. Prompt对话框处理
csharp
/// <summary>
/// 处理prompt对话框
/// </summary>
/// <param name="callback">对话框回调</param>
/// <param name="message">消息内容</param>
/// <param name="defaultValue">默认输入值</param>
/// <param name="url">来源URL</param>
/// <returns>是否已处理</returns>
private bool HandlePrompt(IFBroSharpJSDialogCallback callback, string message,
string defaultValue, string url)
{
Console.WriteLine($"Prompt对话框被拦截: {message}");
Console.WriteLine($"默认值: {defaultValue}");
// 生成智能响应值
string responseValue = GeneratePromptResponse(message, defaultValue, url);
LogDialogInfo("PROMPT", message, url, responseValue);
// 响应prompt对话框
callback.Continue(true, responseValue);
return true;
}
/// <summary>
/// 生成prompt对话框的智能响应
/// </summary>
/// <param name="message">对话框消息</param>
/// <param name="defaultValue">默认值</param>
/// <param name="url">来源URL</param>
/// <returns>响应值</returns>
private string GeneratePromptResponse(string message, string defaultValue, string url)
{
// 优先使用默认值
if (!string.IsNullOrEmpty(defaultValue))
{
return defaultValue;
}
// 根据消息内容判断合适的响应
if (message.Contains("用户名") || message.Contains("username"))
{
return "AutoUser";
}
if (message.Contains("密码") || message.Contains("password"))
{
return "AutoPassword123";
}
if (message.Contains("邮箱") || message.Contains("email"))
{
return "auto@example.com";
}
if (message.Contains("数量") || message.Contains("count"))
{
return "1";
}
// 默认返回空字符串
return string.Empty;
}4. 默认处理器
csharp
/// <summary>
/// 默认对话框处理器
/// </summary>
/// <param name="callback">对话框回调</param>
/// <returns>是否已处理</returns>
private bool HandleDefault(IFBroSharpJSDialogCallback callback)
{
Console.WriteLine("未知类型的JS对话框被拦截");
// 默认确认并关闭
callback.Continue(true, string.Empty);
return true;
}📝 日志记录系统
对话框日志记录
csharp
/// <summary>
/// 记录对话框信息到日志
/// </summary>
/// <param name="type">对话框类型</param>
/// <param name="message">消息内容</param>
/// <param name="url">来源URL</param>
/// <param name="response">响应值(可选)</param>
private void LogDialogInfo(string type, string message, string url, string response = null)
{
var logEntry = new DialogLogEntry
{
Timestamp = DateTime.Now,
Type = type,
Message = message,
OriginUrl = url,
Response = response ?? "N/A"
};
// 记录到控制台
Console.WriteLine($"[{logEntry.Timestamp:yyyy-MM-dd HH:mm:ss}] " +
$"{type} - {message} (URL: {GetDomainFromUrl(url)})");
// 记录到文件(可选)
WriteLogToFile(logEntry);
// 记录到内存列表(用于统计分析)
dialogLogs.Add(logEntry);
}
/// <summary>
/// 对话框日志条目
/// </summary>
public class DialogLogEntry
{
public DateTime Timestamp { get; set; }
public string Type { get; set; }
public string Message { get; set; }
public string OriginUrl { get; set; }
public string Response { get; set; }
}
/// <summary>
/// 对话框日志列表
/// </summary>
private readonly List<DialogLogEntry> dialogLogs = new List<DialogLogEntry>();
/// <summary>
/// 从URL提取域名
/// </summary>
/// <param name="url">完整URL</param>
/// <returns>域名</returns>
private string GetDomainFromUrl(string url)
{
try
{
var uri = new Uri(url);
return uri.Host;
}
catch
{
return url;
}
}
/// <summary>
/// 将日志写入文件
/// </summary>
/// <param name="logEntry">日志条目</param>
private void WriteLogToFile(DialogLogEntry logEntry)
{
try
{
var logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "FBroLogs");
if (!Directory.Exists(logDir))
{
Directory.CreateDirectory(logDir);
}
var logFile = Path.Combine(logDir, $"JSDialogs_{DateTime.Now:yyyyMMdd}.log");
var logLine = $"{logEntry.Timestamp:yyyy-MM-dd HH:mm:ss}|{logEntry.Type}|{logEntry.Message}|{logEntry.OriginUrl}|{logEntry.Response}";
File.AppendAllText(logFile, logLine + Environment.NewLine, System.Text.Encoding.UTF8);
}
catch (Exception ex)
{
Console.WriteLine($"写入日志文件失败: {ex.Message}");
}
}⚙️ 配置管理系统
灵活的配置选项
csharp
/// <summary>
/// JavaScript对话框处理配置
/// </summary>
public class JSDialogConfig
{
/// <summary>
/// 是否启用对话框拦截
/// </summary>
public bool EnableInterception { get; set; } = true;
/// <summary>
/// 是否记录日志
/// </summary>
public bool EnableLogging { get; set; } = true;
/// <summary>
/// Alert对话框的默认处理方式
/// </summary>
public DialogHandleMode AlertHandleMode { get; set; } = DialogHandleMode.AutoConfirm;
/// <summary>
/// Confirm对话框的默认响应
/// </summary>
public bool DefaultConfirmResponse { get; set; } = true;
/// <summary>
/// Prompt对话框的默认响应值
/// </summary>
public string DefaultPromptResponse { get; set; } = "";
/// <summary>
/// 白名单URL列表(这些URL的对话框将正常显示)
/// </summary>
public List<string> WhitelistUrls { get; set; } = new List<string>();
/// <summary>
/// 黑名单URL列表(这些URL的对话框将被完全阻止)
/// </summary>
public List<string> BlacklistUrls { get; set; } = new List<string>();
}
/// <summary>
/// 对话框处理模式
/// </summary>
public enum DialogHandleMode
{
/// <summary>
/// 自动确认
/// </summary>
AutoConfirm,
/// <summary>
/// 完全阻止
/// </summary>
Block,
/// <summary>
/// 显示原生对话框
/// </summary>
ShowNative,
/// <summary>
/// 自定义处理
/// </summary>
Custom
}
/// <summary>
/// 配置实例
/// </summary>
private JSDialogConfig config = new JSDialogConfig();
/// <summary>
/// 加载配置文件
/// </summary>
public void LoadConfig(string configPath = null)
{
try
{
configPath = configPath ?? Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"FBro", "JSDialogConfig.json");
if (File.Exists(configPath))
{
var json = File.ReadAllText(configPath, System.Text.Encoding.UTF8);
config = Newtonsoft.Json.JsonConvert.DeserializeObject<JSDialogConfig>(json) ?? new JSDialogConfig();
Console.WriteLine($"配置文件已加载: {configPath}");
}
else
{
SaveConfig(configPath); // 保存默认配置
Console.WriteLine($"创建默认配置文件: {configPath}");
}
}
catch (Exception ex)
{
Console.WriteLine($"加载配置失败: {ex.Message},使用默认配置");
config = new JSDialogConfig();
}
}
/// <summary>
/// 保存配置文件
/// </summary>
public void SaveConfig(string configPath = null)
{
try
{
configPath = configPath ?? Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"FBro", "JSDialogConfig.json");
var directory = Path.GetDirectoryName(configPath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
var json = Newtonsoft.Json.JsonConvert.SerializeObject(config, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(configPath, json, System.Text.Encoding.UTF8);
Console.WriteLine($"配置文件已保存: {configPath}");
}
catch (Exception ex)
{
Console.WriteLine($"保存配置失败: {ex.Message}");
}
}🎯 实际应用场景
场景1:完全阻止所有弹窗
csharp
/// <summary>
/// 简单粗暴的完全阻止模式
/// 适用于自动化脚本和无人值守应用
/// </summary>
public override bool OnJSDialog(IFBroSharpBrowser browser,
string origin_url,
FBroJsDialogType dialog_type,
string message_text,
string default_prompt_text,
IFBroSharpJSDialogCallback callback,
ref bool suppress_message)
{
// 记录但不显示
Console.WriteLine($"阻止JS对话框: {dialog_type} - {message_text}");
// 自动确认并提供合理的默认值
string defaultResponse = dialog_type == FBroJsDialogType.JSDIALOGTYPE_PROMPT ? "auto" : "";
callback.Continue(true, defaultResponse);
return true; // 完全接管,不显示原生对话框
}场景2:智能处理模式
csharp
/// <summary>
/// 智能处理模式实现
/// 根据内容和来源智能判断处理方式
/// </summary>
public override bool OnJSDialog(IFBroSharpBrowser browser,
string origin_url,
FBroJsDialogType dialog_type,
string message_text,
string default_prompt_text,
IFBroSharpJSDialogCallback callback,
ref bool suppress_message)
{
// 检查是否在白名单中
if (IsUrlInWhitelist(origin_url))
{
Console.WriteLine($"白名单URL,显示原生对话框: {origin_url}");
return false; // 显示原生对话框
}
// 检查是否在黑名单中
if (IsUrlInBlacklist(origin_url))
{
Console.WriteLine($"黑名单URL,完全阻止: {origin_url}");
callback.Continue(false, ""); // 取消操作
return true;
}
// 检查是否为重要提示
if (IsImportantMessage(message_text))
{
Console.WriteLine($"重要消息,显示原生对话框: {message_text}");
return false; // 显示原生对话框
}
// 其他情况自动处理
return HandleDialog(dialog_type, message_text, default_prompt_text, callback);
}
/// <summary>
/// 检查URL是否在白名单中
/// </summary>
private bool IsUrlInWhitelist(string url)
{
return config.WhitelistUrls.Any(whiteUrl =>
url.IndexOf(whiteUrl, StringComparison.OrdinalIgnoreCase) >= 0);
}
/// <summary>
/// 检查URL是否在黑名单中
/// </summary>
private bool IsUrlInBlacklist(string url)
{
return config.BlacklistUrls.Any(blackUrl =>
url.IndexOf(blackUrl, StringComparison.OrdinalIgnoreCase) >= 0);
}
/// <summary>
/// 检查是否为重要消息
/// </summary>
private bool IsImportantMessage(string message)
{
string[] importantKeywords = { "错误", "error", "失败", "failed", "警告", "warning" };
return importantKeywords.Any(keyword =>
message.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0);
}场景3:数据收集模式
csharp
/// <summary>
/// 数据收集模式
/// 专门用于分析网站的JavaScript对话框使用情况
/// </summary>
public class DialogAnalyzer
{
private readonly Dictionary<string, List<DialogData>> dialogsByDomain = new Dictionary<string, List<DialogData>>();
public override bool OnJSDialog(IFBroSharpBrowser browser,
string origin_url,
FBroJsDialogType dialog_type,
string message_text,
string default_prompt_text,
IFBroSharpJSDialogCallback callback,
ref bool suppress_message)
{
// 收集对话框数据
var dialogData = new DialogData
{
Timestamp = DateTime.Now,
Url = origin_url,
Type = dialog_type,
Message = message_text,
DefaultValue = default_prompt_text
};
var domain = GetDomainFromUrl(origin_url);
if (!dialogsByDomain.ContainsKey(domain))
{
dialogsByDomain[domain] = new List<DialogData>();
}
dialogsByDomain[domain].Add(dialogData);
// 自动处理对话框
callback.Continue(true, GetSmartResponse(dialog_type, message_text, default_prompt_text));
// 定期生成分析报告
if (dialogsByDomain.Values.Sum(list => list.Count) % 50 == 0)
{
GenerateAnalysisReport();
}
return true;
}
/// <summary>
/// 生成分析报告
/// </summary>
private void GenerateAnalysisReport()
{
Console.WriteLine("\n=== JavaScript对话框分析报告 ===");
foreach (var domain in dialogsByDomain.Keys)
{
var dialogs = dialogsByDomain[domain];
Console.WriteLine($"\n域名: {domain}");
Console.WriteLine($" 总对话框数: {dialogs.Count}");
Console.WriteLine($" Alert数: {dialogs.Count(d => d.Type == FBroJsDialogType.JSDIALOGTYPE_ALERT)}");
Console.WriteLine($" Confirm数: {dialogs.Count(d => d.Type == FBroJsDialogType.JSDIALOGTYPE_CONFIRM)}");
Console.WriteLine($" Prompt数: {dialogs.Count(d => d.Type == FBroJsDialogType.JSDIALOGTYPE_PROMPT)}");
// 显示最常见的消息
var commonMessages = dialogs.GroupBy(d => d.Message)
.OrderByDescending(g => g.Count())
.Take(3);
Console.WriteLine(" 常见消息:");
foreach (var msg in commonMessages)
{
Console.WriteLine($" \"{msg.Key}\" (出现{msg.Count()}次)");
}
}
Console.WriteLine("================================\n");
}
}
/// <summary>
/// 对话框数据结构
/// </summary>
public class DialogData
{
public DateTime Timestamp { get; set; }
public string Url { get; set; }
public FBroJsDialogType Type { get; set; }
public string Message { get; set; }
public string DefaultValue { get; set; }
}🛠️ 高级功能
自定义对话框替换
csharp
/// <summary>
/// 自定义对话框管理器
/// 用自定义UI替换原生JavaScript对话框
/// </summary>
public class CustomDialogManager
{
/// <summary>
/// 显示自定义Alert对话框
/// </summary>
public void ShowCustomAlert(string message, string title = "提示")
{
// 这里可以显示自定义的WPF或WinForms对话框
System.Windows.Forms.MessageBox.Show(message, title,
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Information);
}
/// <summary>
/// 显示自定义Confirm对话框
/// </summary>
public bool ShowCustomConfirm(string message, string title = "确认")
{
var result = System.Windows.Forms.MessageBox.Show(message, title,
System.Windows.Forms.MessageBoxButtons.YesNo,
System.Windows.Forms.MessageBoxIcon.Question);
return result == System.Windows.Forms.DialogResult.Yes;
}
/// <summary>
/// 显示自定义Prompt对话框
/// </summary>
public string ShowCustomPrompt(string message, string defaultValue = "", string title = "输入")
{
// 这里可以使用自定义的输入对话框
// 简化示例使用InputBox(需要引用Microsoft.VisualBasic)
return Microsoft.VisualBasic.Interaction.InputBox(message, title, defaultValue);
}
}
/// <summary>
/// 带自定义UI的对话框处理
/// </summary>
public override bool OnJSDialog(IFBroSharpBrowser browser,
string origin_url,
FBroJsDialogType dialog_type,
string message_text,
string default_prompt_text,
IFBroSharpJSDialogCallback callback,
ref bool suppress_message)
{
var customDialog = new CustomDialogManager();
// 在UI线程中显示自定义对话框
Application.Current.Dispatcher.Invoke(() =>
{
switch (dialog_type)
{
case FBroJsDialogType.JSDIALOGTYPE_ALERT:
customDialog.ShowCustomAlert(message_text, "网页消息");
callback.Continue(true, "");
break;
case FBroJsDialogType.JSDIALOGTYPE_CONFIRM:
bool confirmed = customDialog.ShowCustomConfirm(message_text, "网页确认");
callback.Continue(confirmed, "");
break;
case FBroJsDialogType.JSDIALOGTYPE_PROMPT:
string input = customDialog.ShowCustomPrompt(message_text, default_prompt_text, "网页输入");
callback.Continue(!string.IsNullOrEmpty(input), input ?? "");
break;
}
});
return true; // 阻止原生对话框显示
}📊 统计分析功能
对话框使用统计
csharp
/// <summary>
/// 对话框统计分析器
/// </summary>
public class DialogStatistics
{
private readonly Dictionary<FBroJsDialogType, int> dialogCounts = new Dictionary<FBroJsDialogType, int>();
private readonly Dictionary<string, int> domainCounts = new Dictionary<string, int>();
private readonly List<DateTime> dialogTimes = new List<DateTime>();
/// <summary>
/// 记录对话框统计
/// </summary>
public void RecordDialog(FBroJsDialogType type, string url)
{
// 记录类型统计
if (dialogCounts.ContainsKey(type))
dialogCounts[type]++;
else
dialogCounts[type] = 1;
// 记录域名统计
var domain = GetDomainFromUrl(url);
if (domainCounts.ContainsKey(domain))
domainCounts[domain]++;
else
domainCounts[domain] = 1;
// 记录时间
dialogTimes.Add(DateTime.Now);
}
/// <summary>
/// 获取统计报告
/// </summary>
public string GetStatisticsReport()
{
var report = new System.Text.StringBuilder();
report.AppendLine("=== JavaScript对话框统计报告 ===");
report.AppendLine($"统计时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
report.AppendLine($"总对话框数: {dialogTimes.Count}");
if (dialogTimes.Count > 0)
{
report.AppendLine($"首次记录: {dialogTimes.Min():yyyy-MM-dd HH:mm:ss}");
report.AppendLine($"最后记录: {dialogTimes.Max():yyyy-MM-dd HH:mm:ss}");
}
report.AppendLine("\n--- 按类型统计 ---");
foreach (var kvp in dialogCounts.OrderByDescending(x => x.Value))
{
report.AppendLine($"{kvp.Key}: {kvp.Value}次");
}
report.AppendLine("\n--- 按域名统计 (前10名) ---");
foreach (var kvp in domainCounts.OrderByDescending(x => x.Value).Take(10))
{
report.AppendLine($"{kvp.Key}: {kvp.Value}次");
}
// 时间分布分析
if (dialogTimes.Count > 1)
{
var hourGroups = dialogTimes.GroupBy(t => t.Hour).OrderBy(g => g.Key);
report.AppendLine("\n--- 按小时分布 ---");
foreach (var group in hourGroups)
{
report.AppendLine($"{group.Key:D2}:00-{group.Key:D2}:59: {group.Count()}次");
}
}
report.AppendLine("================================");
return report.ToString();
}
/// <summary>
/// 清空统计数据
/// </summary>
public void ClearStatistics()
{
dialogCounts.Clear();
domainCounts.Clear();
dialogTimes.Clear();
Console.WriteLine("统计数据已清空");
}
}⚠️ 注意事项
1. 回调处理
- 必须调用callback.Continue():无论采用何种处理方式,都必须调用callback来响应对话框
- 线程安全:callback操作必须在正确的线程上下文中执行
- 资源释放:避免callback被多次调用,确保正确的资源管理
2. 返回值含义
- 返回true:表示已自定义处理该对话框,不会显示原生JavaScript对话框
- 返回false:表示使用浏览器默认处理,会显示原生对话框
- suppress_message:此参数可以控制是否完全抑制消息显示
3. 性能考虑
- 避免阻塞:处理逻辑应该快速完成,避免长时间阻塞浏览器线程
- 内存管理:及时清理日志和统计数据,避免内存泄漏
- 配置优化:合理配置白名单和黑名单,减少不必要的处理
4. 安全注意事项
- 输入验证:对prompt对话框的响应值进行适当的验证和清理
- 敏感信息:避免在日志中记录敏感信息如密码等
- 权限控制:根据安全需求决定是否允许某些域名的对话框正常显示
🏆 最佳实践
1. 配置驱动设计
csharp
// 使用配置文件控制行为,便于动态调整
var config = LoadConfig();
if (config.EnableInterception)
{
// 执行拦截逻辑
}2. 分级处理策略
csharp
// 根据重要性和来源采用不同的处理策略
if (IsSystemCritical(url)) return false; // 显示原生对话框
if (IsUserImportant(message)) return false; // 显示原生对话框
// 其他情况自动处理3. 完善的日志记录
csharp
// 记录详细信息用于调试和分析
LogDialog(type, message, url, response, timestamp);4. 错误处理机制
csharp
try
{
// 对话框处理逻辑
callback.Continue(true, response);
}
catch (Exception ex)
{
// 错误时的安全处理
Console.WriteLine($"对话框处理错误: {ex.Message}");
callback.Continue(false, "");
}通过以上完整的实现方案,您可以全面控制FBro浏览器中的JavaScript对话框行为,实现从简单阻止到智能处理的各种需求。这个功能在自动化测试、网页监控、用户体验优化等场景中都非常有用。