简体   繁体   English

在WebBrowser控件上页面导航后尝试执行JavaScript时出错

[英]Error when trying to execute JavaScript after page navigation on WebBrowser control

I use a WebBrowser control in a WP7 app and have set IsScriptEnabled to true. 我在WP7应用程序中使用WebBrowser控件并将IsScriptEnabled设置为true。 Then when trying to invoke a script via InvokeScript of the WebBrowser I see a strange behavior: The script gets executed correctly on the first page. 然后,当尝试通过WebBrowser的InvokeScript调用脚本时,我看到一个奇怪的行为:脚本在第一页上正确执行。 Then I navigate to another page via Navigate() and try to execute a script I get following error message: 然后我通过Navigate()导航到另一个页面并尝试执行我收到以下错误消息的脚本:

"An unknown error has occurred. Error: 80020006". “发生了未知错误。错误:80020006”。

I have tried to set IsScriptEnabled to true before navigating to the next page - no luck. 我试图在导航到下一页之前将IsScriptEnabled设置为true - 没有运气。 Waiting for the completing of the document loading state doesn't help either. 等待完成文档加载状态也没有帮助。

All HTML files are stored in isolated storage and get displayed correctly. 所有HTML文件都存储在独立存储中并正确显示。 Only the script interaction doesn't work. 只有脚本交互不起作用。

Any ideas? 有任何想法吗?

--edit/quetz: If you have problems with on-page javascripts not running at all: make sure to check my findings on the subject that I've posted at http://social.msdn.microsoft.com/Forums/en-AU/jscript/thread/bac9f056-e0de-449e-a1b6-36e745fa59c6 - maybe your problems are related to some unlucky timings or property-setter ordering. --edit / quetz:如果您在页面上没有运行javascripts时遇到问题:请务必查看我在http://social.msdn.microsoft.com/Forums/en上发布的主题的调查结果-AU / jscript / thread / bac9f056-e0de-449e-a1b6-36e745fa59c6 - 也许你的问题与一些不幸的时间或属性设定器排序有关。 it turns out that if you hardcode the URL in XAML, then you must ensure that in that XAML the IsScriptEnabled is set BEFORE the SOURCE property, or else you will have lots of failures depedent on what doctype your pages have. 事实证明,如果您在XAML中对URL进行硬编码,那么您必须确保在该XAML中,在SOURCE属性之前设置IsScriptEnabled,否则您将有很多失败取决于您的页面具有哪种doctype。 the same applies to setting the Source or Navigate'ing in the code, but that's quite obvious there. 这同样适用于在代码中设置Source或Navigate',但这在那里非常明显。 on the other hand, at first glance, bindings seem to work properly either way. 另一方面,乍一看,绑定似乎无论如何都能正常工作。 --/edit - /编辑

A long time since your posting passed, but if you still have the question in your memory, then maybe it will help you a little. 很长一段时间以来你的帖子都过去了,但是如果你的记忆中仍有问题,那么它可能对你有所帮助。

Let's first think shallow: 让我们先思考一下:

Maybe the page has not loaded yet? 也许页面还没有加载? You say that all pages are on ISO, so they load in a blink of the eye, but still it takes some time. 你说所有的页面都是ISO,因此它们会在眨眼之间加载,但仍需要一些时间。 You only have pointed out the Navigate() method which is a little strange to me, because when InvokeScript()'ing, the most important thing is, to do the invokes it in- or after- receiving the Navigated event . 你只指出了Navigate() 方法 ,这对我来说有点奇怪,因为当InvokeScript()时,最重要的是,在接收Navigated 事件之后或之后调用它。 While you might have it properly implemented, and you might have mistyped the Navigated-event with Navigate() - but according to what you've written, you also could have been trying to do: 虽然您可能已正确实现它,并且您可能使用Navigate()错误地键入了Navigated事件 - 但根据您编写的内容,您也可能尝试这样做:

void myfuntion()
{
    webbrowser.Navigate("pages/index.html");
    webbrowser.InvokeScript("myjsfunc");
}

which will almost never work. 这几乎不会奏效。 the proper way to implement it is: 实现它的正确方法是:

...
    //elsewhere
    webbrowser.Navigated += wb_Navigated;
...

void myfuntion()
{
    webbrowser.Navigate("pages/index.html"); // or webbrowser.Source = ...
}

void wb_Navigated(object sender, NavigationEventArgs e)
{
    webbrowser.InvokeScript("myjsfunc");
}

only in this way you can be sure that the page has loaded. 只有这样你才能确定页面已加载。 Without it, it's you are almost guaranteed to fail. 没有它,你几乎可以保证失败。

However, you would probably get a 0x80020101 hresult in such case. 但是,在这种情况下,您可能会获得0x80020101的结果。

That one, at least in the 7.0, 7.1 and 7.5 sdk releases, is used when the JS engine encounters a symbol is not understood. 至少在7.0,7.1和7.5版本的sdk版本中,当JS引擎遇到符号时,会使用该版本。 This error is also reported for many other cases, too, but this is the most common. 许多其他情况也会报告此错误,但这是最常见的。 Whenever you try to call enything that contains undefined names - you will see 0x80020101. 每当您尝试调用包含未定义名称的enything时,您将看到0x80020101。 For example, InvokeScript("eval", "askdjaslkdsajdla") will throw that, assuming this variable is not created to fool the example:) 例如,InvokeScript(“eval”,“askdjaslkdsajdla”)会抛出它,假设这个变量不是为了欺骗示例而创建的:)

I'm writing about that, because if you are NOT reacting to the Navigated and make calls prematurely, then the in-memory-page may still be the old-page with old-contents, and thus the names you try tu refer could be missing. 我正在写这个,因为如果你没有对Navigated作出反应并过早地拨打电话,那么内存页面可能仍然是旧内容的旧页面,因此你尝试参考的名字可能是失踪。

But, if you really see 80020006 (which is namenotfound but from OLE layer), then I'd assume the problem is elsewhere. 但是,如果你真的看到80020006(这是名称发现但是来自OLE层),那么我认为问题出在其他地方。 Then, we have to dig deeper.. 然后,我们必须深入挖掘..

Whenever you try to call a InvokeScript during the Navigated-event-handler, then you might fall a victim to a very random (at least from my experience) bug in the webbrowser. 每当您尝试在Navigated-event-handler期间调用InvokeScript时,您可能会成为webbrowser中非常随机(至少从我的经验)错误的受害者。 Simply: sometimes, despite receiving 'Navigated' notification, the WebBrowser is not actually yet in a fully-prepared/rendered/wtf condition. 简单地说:有时,尽管收到“导航”通知,但WebBrowser实际上还没有处于完全准备/渲染/ wtf状态。

I dont know exactly when, I suppose it's connected to either the page size, scripts size/time, or amount of external linked resources. 我不确切知道什么时候,我认为它与页面大小,脚本大小/时间或外部链接资源的数量有关。

When this happens you will be observing ComException other than 0x80020101, and I'm almost sure that it would be the 80020006. Simple InvokeScripts like ("eval", "mom") may execute and run correctly, but the more complicated it is, the smaller chances. 当发生这种情况时,您将观察除0x80020101以外的ComException,并且我几乎可以肯定它将是80020006.简单的InvokeScripts(“eval”,“mom”)可以正确执行和运行,但它越复杂,机会越小。 For example, when it happens, ALL scripts referring directly to the body element, or its children - will instantly fail upon resolving that symbol. 例如,当它发生时,直接引用body元素或其子元素的所有脚本在解析该元素时将立即失败。 If you use libraries like jQuery - you may not event have the reference to body explicitly stated - if the library touches it, it will fail just in the same way, with the same exception. 如果你使用像jQuery这样的库 - 你可能没有事件明确声明了body的引用 - 如果库接触它,它将以相同的方式失败,具有相同的异常。 Strangely, the document.head is not affected by the problem it, and you may refer to it with no problems. 奇怪的是,document.head不受问题的影响,你可以毫无问题地引用它。 From my observations, only the body is problematic in such cases. 根据我的观察,在这种情况下只有身体是有问题的。

Actually, after writing that - I see that probably your case is may exactly like that, as you try to modify 'document.body.style.fontSize'.. 实际上,在写完之后 - 我看到你的情况可能就是这样,因为你试图修改'document.body.style.fontSize'..

Anyways, there is no instant way to solve the problem, because the problem is somewhere in the internal timings of the webbrowser, and it happens to be reporting 'Navigated' too soon. 无论如何, 没有即时的方法来解决问题,因为问题出现在webbrowser的内部时间中,并且恰好是过早报告“导航”。 I'm sure it is hideous a bug in the webbrowser, and maybe they will fixing in some future release. 我确定它在Web浏览器中是一个可怕的错误,也许它们将在未来的某个版本中修复。 Until that, the only way to handle it, is ... to delay your invocation, until the browser really finishes parsing the page. 在此之前,处理它的唯一方法是...延迟调用,直到浏览器真正完成解析页面。

To say it in other words: If you are trying to properly call InvokeScript in the browser.Navigated handler, you may get an exception different than 0x80020101 (which would mean that your js-code given to InvokeScript is bad formed). 换句话说:如果你试图在browser.Navigated处理程序中正确调用InvokeScript,你可能会得到一个不同于 0x80020101的异常(这意味着你给InvokeScript的js代码形成不好)。 If you catch such error (probably 80020006), then check whether you can 'touch' the document.body via the invokescript. 如果你遇到这样的错误(可能是80020006),那么检查你是否可以通过invokescript“触摸”document.body。 if you get different error, then this is NOT the case. 如果你得到不同的错误,那么事实并非如此。 But, if you get the SAME error, then most probably it is the case, and the problem is your-or-webbrowser's unlucky timing. 但是,如果你得到相同的错误,那么很可能就是这种情况,而问题是你或者webbrowser不幸的时机。 You have to abort your attempts, start a timer of 125..500 milliseconds, return from the handler so the browser will be allowed to continue its internal jobs, and then, when the timer elapses - retry the original call and pray. 您必须中止尝试,启动125..500毫秒的计时器,从处理程序返回,以便允许浏览器继续其内部作业,然后,当计时器过去时 - 重试原始呼叫并祈祷。 And during that delayed attept, you also must listen for exceptions in the same way, because you may get the same error again, and again, and again (..). 在延迟注意期间,您还必须以相同的方式监听异常,因为您可能会再次获得相同的错误,并且再次(...)。

From my experiments, 500ms was always enough in such cases, but it was ugly for the user-experience. 从我的实验来看,在这种情况下,500毫秒总是足够的,但它对于用户体验来说是丑陋的。 125 was quite unnoticeable, but then - sometimes it was too quick, and 2-3 retries had to be done.. 125是非常不明显的,但随后 - 有时它太快了,必须完成2-3次重试。

But, whatever happens - once you Navigate, receive Navigated, then successfully touch the document.body -- the timingerror will never occur again, for that page. 但是,无论发生什么 - 一旦你导航,接收导航,然后成功触摸document.body - timingerror将永远不会再发生,对于该页面。 Once the internal browser's gears get running, the InvokeScript will work like a charm, well, until you load next page.. ;) 一旦内部浏览器的齿轮运行,InvokeScript将像魅力一样工作,直到你加载下一页..;)

From my experience, if you can control the raw source of the page, you may also try a bit simpler workaround - in your page, somewhere in the body, place: 根据我的经验,如果你可以控制页面的原始来源,你也可以尝试一些更简单的解决方法 - 在你的页面,身体的某个地方,地方:

<script type="text/javascript"> window.external.notify('somestringyouwillknow');  </script>

and in your C# or XAML code, attach to WebBrowser.ScriptNofity event. 并在您的C#或XAML代码中,附加到WebBrowser.ScriptNofity事件。 Whenever your that page loads, it will invoke that ScriptNotify and provide you with the string you have written there. 每当你加载那个页面时,它都会调用ScriptNotify并为你提供你在那里写的字符串。 It will surely arrive after the Navigated event, and if you catch such ScriptNotify notification - it is obvious that the JS engine has loaded and that the body is at least partially parsed, and probaly also the document.body will be initialized and touchable. 它肯定会在Navigated事件之后到达,并且如果你发现了这样的ScriptNotify通知 - 显然JS引擎已经加载并且主体至少被部分解析,并且可能还会初始化和触摸document.body。

80020006 can be shown for a variety of reasons due to failing to execute the required function. 由于未能执行所需功能,可能由于各种原因而显示80020006。 Typically this is experienced when the function cannot be found. 通常,在无法找到该功能时会遇到这种情况。
Ensure that you are loading the correct version of the file which contains the function and not an old cached version. 确保您正在加载包含该函数的文件的正确版本,而不是旧的缓存版本。
Caching on the phone can be very aggressive so please don't assume that you have the latest version of the file loaded. 在手机上缓存可能非常激进,所以请不要假设您已加载最新版本的文件。 When in doubt, change the files contents so that you can see that it is the latest/appropriate version. 如有疑问,请更改文件内容,以便您可以看到它是最新/适当的版本。

Update 更新
As it seems you're trying execute code against arbitrary pages that have been browsed to on the web you may be having the same issue as documented at http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/e00942e4-e40c-4e80-b112-30ca0709fbc8/ 由于您似乎正在尝试对在网络上浏览过的任意页面执行代码,因此您可能遇到与http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/中记录的相同的问题。 线程/ e00942e4-e40c-4e80-b112-30ca0709fbc8 /

This may also be related: http://social.msdn.microsoft.com/Forums/en-US/mktplace/thread/4ae5f139-f8b2-495b-860f-01075b735ee7/ 这也可能是相关的: http//social.msdn.microsoft.com/Forums/en-US/mktplace/thread/4ae5f139-f8b2-495b-860f-01075b735ee7/

Make sure all your pages have DOCTYPE tag, something like 确保所有页面都有DOCTYPE标记,例如

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

I also found that including a piece of javascript, even an empty pair of tags helps as well: 我还发现包含一段javascript,甚至一对空标签也有帮助:

<html>
    <head>
        <script></script>
        ...  
  <head>
  <body>
      ...
  </body>
</html>     

I've seen this error in three situations: 我在三种情况下看到了这个错误:

  1. When there's a JavaScript error in the function in the page you are calling into. 当您调用的页面中的函数出现JavaScript错误时。 Try debugging the page in Chrome paying special attention to the inspector. 尝试在Chrome中调试页面,特别注意检查员。 You might need to add some scaffolding to play as your C# code during this debugging process. 在此调试过程中,您可能需要添加一些脚手架作为C#代码。
  2. When the WebBrowser control is not correctly attached to the XAML layout. WebBrowser控件未正确附加到XAML布局时。 For example, when the control is in a grid but does not have Grid.Row or Grid.Column attributes set or if they are out of bounds. 例如,当控件位于网格中但没有设置Grid.RowGrid.Column属性时,或者它们是否超出范围。
  3. When using the WebBrowser.Loaded event instead of the WebBrowser.LoadCompleted event as the trigger for eventually calling InvokeScript() 使用WebBrowser.Loaded事件而不是WebBrowser.LoadCompleted事件作为最终调用InvokeScript()的触发器时

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

相关问题 在webbrowser控件中执行javascript - Execute javascript in webbrowser control 尝试使用VBA在webbrowser控件上执行javascript命令 - Trying to use VBA to execute a javascript command on a webbrowser control 升级到 jQuery 1.6.2 后,globalEval 在页面上尝试执行 javascript 时抛出错误 - After upgrading to jQuery 1.6.2, globalEval throws an error when trying to execute javascript on page 在webbrowser控件中执行附加到htmlelement的javascript - execute javascript attached to htmlelement in webbrowser control 使用Webbrowser控件和https时出现Javascript错误,但它在IE中有效 - Javascript error when using Webbrowser control and https , yet it works in IE 在WPF WebBrowser控件中禁用JavaScript错误 - Disable JavaScript error in WPF WebBrowser control WP7 webBrowser 控件出现 Javascript 错误! - Javascript error in WP7 webBrowser control! 如何在不修改webbrowser控件中的文档的情况下注入并执行javascript函数? - How to inject and execute a javascript function without modifiting document in webbrowser control? 访问我无法控制的特定页面时执行JavaScript - Execute JavaScript when visiting a specific page that I don’t control 在托管WebBrowser控件的应用程序中,如何在由WebBrowser控件查看的页面中调用JavaScript函数? - How might I call a JavaScript Function in a Page Viewed by a WebBrowser Control from the Application Hosting the WebBrowser Control?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM