简体   繁体   English

覆盖javascript全局变量的可靠方法

[英]Reliable way to override javascript globals

I'm trying to mock the date on a CefSharp browser by injecting MockDate and setting it to some fixed date before every other script runs. 我试图通过注入MockDate并将其设置为每个其他脚本运行之前的某个固定日期来模拟CefSharp浏览器上的日期。 Every window object, on any frame, at any time, should only have access to the mocked date, so the ideal would be to internally redefine the JavaScript Date object, but I don't think CefSharp or probably even Chromium has this option. 任何时候在任何框架上的每个window对象都应该只能访问模拟日期,因此理想的方法是在内部重新定义JavaScript Date对象,但是我不认为CefSharp甚至Chromium都具有此选项。 I'm also going to mock some other functions like setTimeout and Math.rand , to prevent the browser from having any side effects (this is part of a larger project whose aim is to be able to record/replay browsing activity), so messing with OS's time wouldn't solve it. 我还将模拟其他一些函数,例如setTimeoutMath.rand ,以防止浏览器产生任何副作用(这是一个较大的项目的一部分,该项目的目的是能够记录/重放浏览活动),所以很混乱操作系统的时间无法解决问题。

I considered using RegisterJsObject since it can actually overwrite existing globals, but I don't think there is a way to pass a JavaScript constructor. 我考虑使用RegisterJsObject,因为它实际上可以覆盖现有的全局变量,但我认为没有办法传递JavaScript构造函数。

What I've tried so far is to handle the FrameLoadStart event: 到目前为止,我尝试过的是处理FrameLoadStart事件:

private static string Inject = File.ReadAllText("Inject.js");

private void ChromeBrowser_FrameLoadStart(object sender, FrameLoadStartEventArgs e)
{
    e.Frame.ExecuteJavaScriptAsync(Inject);
}

Where "Inject.js" contains the mock date code. 其中“ Inject.js”包含模拟日期代码。 But I've noticed that, randomly, sometimes it'll work and sometimes it won't. 但我注意到,有时它会起作用,有时却不会。 I guess because the function is async and the javascript context sometimes haven't been created, since according to the documentations you shouldn't run scripts here. 我猜是因为该函数是异步的,并且有时尚未创建javascript上下文,因为根据文档,您不应在此处运行脚本。 The documentation recommends handling OnContextCreated instead, but it only runs for the main frame, which wouldn't let me inject the code on any iframe. 该文档建议改为处理OnContextCreated ,但它仅在主要框架上运行,这不允许我在任何iframe上注入代码。 So I wonder if I have any alternative. 所以我想知道我是否还有其他选择。

In case anyone else need this, the solution was to modify the actual C++ CefSharp code by adding a line to the end of CefAppUnmanagedWrapper::OnContextCreated : 万一其他人需要,解决方案是通过在CefAppUnmanagedWrapper::OnContextCreated的末尾添加一行来修改实际的C ++ CefSharp代码:

frame->ExecuteJavaScript(CodeToInject, "something://something", 1);

This won't work if injected on the C# side, I believe because these calls are async so you may be injecting it too late, after scripts on the page have already run. 如果在C#端进行注入,则无法使用,我相信是因为这些调用是异步的,所以在页面上的脚本已经运行之后,您可能注入的太晚了。

If you can edit HTML entry points then you can just add window.Date = MockDate before any other scripts. 如果可以编辑HTML入口点,则只需在其他任何脚本之前添加window.Date = MockDate For example: 例如:

<html>
<body>
<script src="mockdate.js"></script>
<script>
    window.Date = MockDate
</script>
<script src="myscript.js"></script>
</body>
</html>

So the idea is you can tune script loading order in your HTML. 因此,您可以在HTML中调整脚本加载顺序。 It can be done in any browser. 可以在任何浏览器中完成。

If you can not or do not want to edit HTML then it's much trickier. 如果您不能或不想编辑HTML,则要麻烦得多。 You could use CefLoadHandler in CEF C++ or its alternative in CefSharp. 您可以在CEF C ++中使用CefLoadHandler或在CefSharp中使用它的替代方法。

UPD Actually i'm not sure about CefLoadHandler. UPD实际上,我不确定CefLoadHandler。 The reliable way would be to implement your own CefRenderProcessHandler But you already mentioned it. 可靠的方法是实现自己的CefRenderProcessHandler,但您已经提到过。 If it doesn't work then it's a bug in CefSharp or CEF C++ itself. 如果不起作用,则说明CefSharp或CEF C ++本身存在错误。 In that case it would be better to write about it on http://magpcss.org/ceforum/ 在这种情况下,最好将其写在http://magpcss.org/ceforum/上

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在现代浏览器中覆盖全局变量 - Override globals in modern browsers 使用 Javascript 检测操作系统的可靠方法是什么? - What is the reliable way to detect OS using Javascript? 在C#中运行Javascript最可靠的方法? - Most reliable way to run Javascript in C#? 检查对象是否可在JavaScript中序列化的可靠方法 - Reliable way to check if objects is serializable in JavaScript javascript 有没有办法覆盖文档? - javascript is there a way to override document? 有没有其他方法可以访问已被隐藏或重新定义的 JavaScript 全局变量? - Is there any alternative way to access JavaScript globals that have been shadowed or redefined? 有没有一种可靠的方法来计算浏览器中播放音频文件的javascript动画? - Is there a reliable way to time javascript animations with an audio file playing in the browser? 有没有一种可靠的方法来检测所有设备上的滚动,使用javascript / jQuery? - Is there a reliable way to detect scrolling, on all devices, using javascript/jQuery? 检查JavaScript变量是否为空的最可靠方法是什么? - What's the most reliable way to check if a JavaScript variable is null? 在IE中为SaveAs对话框执行特征/对象检测的可靠Javascript方法 - Reliable Javascript way to do feature/object detection for SaveAs dialog in IE
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM