【问题标题】:Intermittent Blazor Server-side Error: $ is not a function间歇性 Blazor 服务器端错误:$ 不是函数
【发布时间】:2022-06-18 05:12:17
【问题描述】:

我在我的日志中看到一个错误,我希望为我的 Blazor 服务器端应用程序追踪该错误。自从二月份部署以来,我已经以一种或另一种方式看到了这一点。这似乎是间歇性发生的,我似乎无法在我自己的本地开发环境或我的测试、暂存和生产环境中重现它。

换句话说,这似乎是一个罕见的、间歇性的、但令人讨厌的问题。如果可能,我想修复它。

这发生在OnAfterRenderAsync 调用中,该调用调用IJsRuntime.Invoke*Async 方法。它将导致如下消息:

Microsoft.JSInterop.JSException: window.$ is not a function
TypeError: window.$ is not a function
    at Module.NewDocumentElement (https://<site>/_content/DragonSpark.Presentation//Environment/Browser/Document/DocumentElement.js:11:43)
    at https://<site>/_framework/blazor.server.js:1:3501
    at new Promise (<anonymous>)
    at kt.beginInvokeJSFromDotNet (https://<site>/_framework/blazor.server.js:1:3475)
    at https://<site>/_framework/blazor.server.js:1:72001
    at Array.forEach (<anonymous>)
    at kt._invokeClientMethod (https://<site>/_framework/blazor.server.js:1:71987)
    at kt._processIncomingData (https://<site>/_framework/blazor.server.js:1:70029)
    at vt.connection.onreceive (https://<site>/_framework/blazor.server.js:1:64432)
    at WebSocket.o.onmessage (https://<site>/_framework/blazor.server.js:1:48766)
   at async ValueTask<TValue> Microsoft.JSInterop.JSRuntime.InvokeAsync<TValue>(long targetInstanceId, string identifier, object[] args)
   at async ValueTask<TOut> DragonSpark.Model.Operations.SelectingResult<TIn, TOut>.Get() in D:/a/1/s/Framework/DragonSpark/Model/Operations/SelectingResult.cs:line 23
   at async ValueTask<TOut> DragonSpark.Model.Operations.OperationResulting<TIn, TOut>.Get() in D:/a/1/s/Framework/DragonSpark/Model/Operations/OperationResulting.cs:line 30
   at async Task DragonSpark.Presentation.Components.Dialogs.DialogClassMonitor.OnAfterRenderAsync(bool firstRender) in D:/a/1/s/Framework/DragonSpark.Presentation/Components/Dialogs/DialogClassMonitor.razor:line 39

在执行的时候,此时似乎没有加载jQuery,但它在我的文档的head中作为我的文档的第一个script标签列出:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    <base href="/" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
    <link rel="manifest" href="/site.webmanifest">
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
    <meta name="msapplication-TileColor" content="#2d89ef">
    <meta name="theme-color" content="#b5dce8">

    <!-- CSS links (omitted) -->

    <!-- CDN-based Scripts -->
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
    <script src="https://cdn.syncfusion.com/blazor/20.1.52/syncfusion-blazor.min.js" type="text/javascript"></script>

    <!-- Meta/OpenGraph links -->

</head>

我也尝试将我的 CDN 脚本标签移动到正文,但这似乎也没有任何好处。错误仍然会发生——虽然很少,但仍然会发生。

我们将不胜感激任何指导和/或建议来解决这个棘手的问题。

【问题讨论】:

  • 我会尽量不在 Blazor 应用程序中使用 jQuery —— 操作 HTML?这就是 Blazor 的用途!但我想这是你冒险吊死自己的绳索。我同意以上所述,$() 应该始终可以通过互操作获得,所以我很难过。改为调用jQuery() 是否有效?
  • 哈哈!我实际上非常同意你的心态@PatrickSzalapski。我不是 jQuery 的粉丝,可能没有它。尽管如此,我在这里的潜在担忧是,如果它发生在一个 CDN 链接上,它会发生在其中任何一个链接上,并且很高兴获得一些关于为什么会发生这种情况的见解/指导。
  • 太好了,谢谢!那么,调用jQuery() 而不是$() 是否有效?只是一个想法;我猜你会得到同样的结果。
  • 感谢@PatrickSzalapski 的建议。我很确定它会以相同的结果结束。这里的问题是 CDN 资源似乎没有以某种间歇性方式为 Blazor 加载/准备(自报告以来我没有看到此错误)。它碰巧在 jQuery 上失败了,因为它是第一个/最流行的。
  • FWIW @PatrickSzalapski 我确实尝试了 jQuery 并遇到了同样的问题。我能够在本地重现这一点,并从我的回答中找到了一个解决方案。似乎是我可能会向 Google 报告的浏览器问题。

标签: javascript jquery blazor blazor-server-side blazor-webassembly


【解决方案1】:

当您从 Blazor 执行 Jsinterop 调用以调用 .js 脚本时,blazor 无法理解查询选择器“$”符号。你需要做的是替换

$() -> document keyword
ex document.getElementById("foo")

来自在 OnAfterRenderAsync 中调用的脚本。

【讨论】:

  • 感谢您的回答,Wajeeh。虽然这是一个很好的解决方法(我可能最终会这样做),但我更担心 Blazor 无法使用 jQuery,尽管它是我文档的 head 中的第一个 script 标记。请注意,window.$“大部分”时间都可以正常工作,但上述情况也会间歇性失败,这就是我要在这里追踪的内容。
  • 谢谢迈克,当你找到合适的解决方案时请告诉我,这就是我在临时修复时遇到类似问题时所做的。
【解决方案2】:

通过多次刷新我的 Blazor 服务器端应用程序,我能够在本地计算机上重现此问题。每 20-30 次尝试中约有 1 次会产生此错误。

原来这与 Blazor 无关,但似乎是浏览器的问题。 code.jquery.com 中的 js 文件根本无法加载,尽管它是我的 head 标记中的第一个脚本。它不会出现在开发者工具的Sources 选项卡中。

我通过做三件事来解决这个问题:

  1. 将我的 CDN 脚本标签作为我的 head 标签中的第一个资源。之前他们在 CSS 文件之后。他们现在是第一个。
  2. 使用下面的slim.min.js 变体(这似乎与文件大小有关)
  3. 使用了如下所示的两个标签:
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js" type="text/javascript"></script>

即使文档中有两个标签,Sources 选项卡也只显示一个。此外,似乎如果一个标签加载失败,则另一个标签会取代它。这似乎是 Chrome 的错误或奇怪的事情。也许我会向 Google 报告。

【讨论】:

    猜你喜欢
    • 2020-06-22
    • 2011-01-05
    • 2012-08-22
    • 2013-11-18
    • 2019-11-22
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 2021-10-08
    相关资源
    最近更新 更多