webview_cef中NavigationDelegate实现异常求助:URL全被拦截
问题分析与修正方案
1. 先查C++层的导航拦截逻辑
WebViewCEF的C++端OnBeforeBrowse方法是核心,常见错误点:
- 直接默认返回
true(CEF里返回true=阻止导航),没根据Dart的决策动态调整 - 异步回调处理乱了,Dart还没返回结果就直接执行了拦截
修正后的C++关键代码示例
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, bool is_redirect) { std::string url = request->GetURL(); // 把导航请求发给Dart层,等它返回决策 SendNavigationRequestToDart(url); // 这里要等Dart的决策返回,不能直接return true bool allow_navigation = WaitForDartDecision(url); // 自己实现同步等待/异步回调关联逻辑 // CEF规则:返回true=阻止,false=允许,别搞反了 return !allow_navigation; }
2. 检查Dart层的决策传递逻辑
Dart层要明确返回允许或阻止的信号,不能模糊传递:
// 接收C++发来的导航请求 void _handleNavigationRequest(String url) { // 按业务逻辑判断是否允许 NavigationDecision decision = url.startsWith("https://my-allowed-domain.com") ? NavigationDecision.navigate : NavigationDecision.prevent; // 把决策明确传给C++,比如用0代表允许,1代表阻止 _channel.invokeMethod("sendNavigationDecision", { "url": url, "decision": decision == NavigationDecision.navigate ? 0 : 1, }); }
3. 确保C++正确接收并应用决策
C++端要把Dart返回的决策和对应请求关联上,避免混乱:
// 用map存Dart返回的决策,URL当key std::unordered_map<std::string, bool> _decision_map; std::mutex _decision_mutex; // 接收Dart的决策 void OnDartNavigationDecision(const std::string& url, int decision) { std::lock_guard<std::mutex> lock(_decision_mutex); // 0=允许导航,对应CEF返回false _decision_map[url] = (decision == 0); } // 在OnBeforeBrowse里拿决策 bool OnBeforeBrowse(...) { std::string url = request->GetURL(); std::lock_guard<std::mutex> lock(_decision_mutex); bool allow_nav = false; auto it = _decision_map.find(url); if (it != _decision_map.end()) { allow_nav = it->second; _decision_map.erase(it); // 用完就清,避免内存泄漏 } return !allow_nav; }
4. 额外排查点
- 别忽略重定向:
OnBeforeBrowse的is_redirect参数要考虑,避免误拦截重定向请求 - Frame判断:如果只拦截主Frame,加个
if (!frame->IsMain()) return false; - 线程安全:C++的决策map一定要加锁,多线程访问容易出问题
内容的提问来源于stack exchange,提问作者JEET NADIYADARA
相关产品推荐
相关产品推荐

