我正在使用 cefsharp 创建自己的应用程序,并使用 ExecuteScriptAsync 将 javascript 发送到正在查看的网站。然而,我遇到了一个问题,我需要使用的元素嵌套在一个 iframe 中,而 iframe 又嵌套在另一个 iframe 中。
我尝试执行以下操作:
var firstIframe = document.querySelector("iframe[title='第一个 Iframe']"); varfirstIframeWindow =firstIframe.contentWindow; var secondaryIframe = firstIframeWindow.document.querySelector('iframe[title="第二个 Iframe"]');
错误示例 由于 iframe 来自不同的域,因此会被跨源阻止。起初我以为我可以通过搞乱 CORS 来解决这个问题。我尝试了各种禁用 CORS 保护的选项。即使使用 --disable-web-security 参数并验证 CORS 是否允许一切通过 https://webbrowsertools.com/test-cors/ 我决定尝试以不同的方式攻击它。
我注意到在 chrome devtools 中,您可以从下拉列表中选择 iframe 来更改 javascript 控制台上下文。嘿,这样做,我可以选择需要交互的 iframe,发送 javascript 代码并与 DOM 元素交互。但是,我是个新手,不知道如何告诉 cefsharp 使用 ExecuteScriptAsync 发送 javascript 的 iframe。救命!!!
我百分百接受各种想法。修复跨源错误或告诉 cefsharp 哪个 iframe 要“聚焦”的方法,或者任何您想要调用它来选择将 javascript 发送到的 iframe 的方法。我会嘲笑它很可能是多么简单,但我想有人可以给我指出正确的方向。
编辑: 我发现一些我认为可以通过实现 Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e) 来工作的东西。
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
// Execute script in the main frame
// browser.ExecuteScriptAsync("alert('Hello from main frame');");
}
else if (!string.IsNullOrEmpty(e.Frame.Name) && e.Frame.Name.Contains("init_timestamp") && !e.Frame.Name.Contains("sandbox"))
{
// Execute script in a specific iframe
browser.ExecuteScriptAsync("alert('Hello from iframe');");
}
}
我觉得这已经很接近了,但又需要将 javascript 发送到正确的 iframe 而不是 Top。 Cefsharp 似乎能够检测到 iframe,但是当它发送到控制台时,它会将其发送到 Top 而不是检测到的 iframe。
我确实通过作弊找到了解决办法。编辑主机文件以阻止此嵌套 AD 所来自的单个域 (rokt.com)。不过,我确实想显示广告。这并没有解决能够将 javascript 发送到与 Top 不同的框架的根本问题。
您需要针对特定框架执行 JavaScript。例如
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
// Execute script in the main frame
e.Frame.ExecuteScriptAsync("alert('Hello from main frame');");
}
else if (!string.IsNullOrEmpty(e.Frame.Name) && e.Frame.Name.Contains("init_timestamp") && !e.Frame.Name.Contains("sandbox"))
{
// Execute script in a specific iframe
e.Frame.ExecuteScriptAsync("alert('Hello from iframe');");
}
}