通过 SignalR 在 IE 中缺少原型方法

2024-04-20

我遇到了一个问题,即仅在 IE 中并且仅当数组通过 SignalR 时才处理原型方法消失(在本例中为 Array.prototype 方法)。

我写了一个小/愚蠢但简单的概念验证网络应用程序来演示这个问题(代码全部在下面)。请注意,当您单击“更新所有客户端”,然后单击“包含字母“r”的水果”时,_list 中的原型方法丢失,从而导致异常。在这种情况下,数组来自 SignalR。现在,当您单击“重置”并将数组重置为硬编码值时,“包含字母“r”的水果”按钮突然起作用 - 原型方法又回来了。请记住,此问题仅发生在 IE 中。

提示:当我第一次编写概念证明时,我无法重现该问题。当数组通过 SignalR 传入时,IE 仍然具有原型方法,但在加载页面时确实出现了另一个错误。我不小心包含了 jQuery 两次。当我取出多余的脚本来包含第二个 jQuery 时,它修复了该错误(显然),但现在问题可以重现。然后,IE 缺少我创建的数组原型方法,但仅当数组通过 SignalR 提供时。

myExtensions.js:

Array.prototype.where = function (del)
{
    var ret = new Array();
    for (var i = 0; i < this.length; i++)
    {
        if (del(this[i])) ret.push(this[i]);
    }
    return ret;
}

Array.prototype.select = function (del)
{
    var ret = new Array();
    for (var i = 0; i < this.length; i++)
    {
        ret.push(del(this[i]));
    }
    return ret;
}

_布局.cshtml

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <meta name="viewport" content="width=device-width" />

        @Styles.Render("~/Content/css")

        @Scripts.Render("~/Scripts/myExtensions.js")
        @Scripts.Render("~/bundles/modernizr")
        @Scripts.Render("~/Scripts/jquery-1.7.1.js")
        @Scripts.Render("~/Scripts/jquery.signalR-1.0.0-rc1.js")
        <script src="~/signalr/hubs"></script>

    </head>
    <body>
        <header>
            <div class="content-wrapper">
                <div class="float-left">
                    <p class="site-title">@Html.ActionLink("IE/SignalR error POC", "Index", "Home")</p>
                </div>
            </div>
        </header>
        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">
                @RenderBody()
            </section>
        </div>
        <footer>
            <div class="content-wrapper">
                <div class="float-left">
                    <p>&copy; @DateTime.Now.Year - My ASP.NET MVC Application</p>
                </div>
            </div>
        </footer>
        @*@Scripts.Render("~/Scripts/myExtensions.js")*@
    </body>
</html>

ListHub.cs

using System.Linq;
using Microsoft.AspNet.SignalR.Hubs;

namespace SignalR_Bug_POC.Hubs
{
    public class ListHub : Hub
    {
        public void RunTest()
        {
            Clients.All.updateList(new string[]
                {
                    "apple", "pear", "grape", "strawberry", "rasberry", "orange", "watermelon"
                }.Select(f => new { Name = f }).ToList());
        }
    }
}

索引.cshtml

@{
    ViewBag.Title = "Home Page";
}

@if(false)
{
    @Scripts.Render("~/Scripts/jquery.signalR-1.0.0-rc1.js")
    @Scripts.Render("~/Scripts/myExtensions.js")
    <script src="~/signalr/hubs"></script>
}

<script type="text/javascript">

    var _fruits = ["blueberry", "grape", "orange", "strawberry"].select(function (f) { return { "Name": f } });
    var _list;

    var conn = $.connection.listHub;
    $.connection.hub.start();

    conn.client.updateList = function (data)
    {
        _list = data;
        $("#theList").html("");
        for (var i = 0; i < _list.length; i++)
        {
            $("#theList").append("<li>" + _list[i].Name + "</li>");
        }
    }

    $(document).ready(function ()
    {
        $("#cmdUpdateClients").click(function ()
        {
            conn.server.runTest();
        });
        $("#cmdReset").click(function ()
        {
            conn.client.updateList(_fruits);
        });
        $("#cmdRunTest").click(function ()
        {
            var message = "";
            var fruitsContaining = _list
                .where(function (f) { return f.Name.indexOf('r') >= 0 })
                .select(function (f) { return f.Name });
            for (var i = 0; i < fruitsContaining.length; i++)
            {
                message += " - " + fruitsContaining[i] + "\n";
            }
            alert(message);
        });
        conn.client.updateList(_fruits);
    });


</script>

<input type="button" id="cmdUpdateClients" value="Update All Clients" />
<input type="button" id="cmdReset" value="Reset" />
<input type="button" id="cmdRunTest" value="Fruits containing the letter r." />
<ul id="theList"></ul>

我不确定这是否是我在代码中做错的事情(即我以错误的顺序做的事情),或者是 IE 错误还是 SignalR 错误。例如,当我在 conn.client.updateList JS 方法的第一行设置断点并跟踪调用堆栈到最顶部时,发现即使在“数据”对象中(在 SignalR 接收方法中)数组也不会没有我的原型方法。


我遇到了同样的问题:当我使用 SignalR 将数组从 C# 传递到 Angular 应用程序时,我无法使用中定义的方法Array.prototype在收到的物体上。此外,从某些数组测试描述的意义上来说,这些对象确实是“类似数组”的here https://stackoverflow.com/questions/4775722/check-if-object-is-array会失败的。例如,arr instanceof Array会回来false, but Array.isArray(arr)会回来true.

当 Web 应用程序托管在没有 WebSocket 支持的 IIS 中时,问题就会出现。在这种情况下,SignalR 默认值 http://www.asp.net/signalr/overview/getting-started/introduction-to-signalr在 Chrome 和 Firefox 中为 serverSentEvents,在 Internet Explorer 和 Edge 中为 ForeverFrame。

正如这个问题所示 https://stackoverflow.com/questions/31578626/signalr-deserializes-my-objects-incorrectly-in-iis-7-5-and-edge-ie-foreverframe,ForeverFrame 导致数组被错误地反序列化。这是因为ForeverFrame使用不同的框架来维护SignalR连接,并且不同框架中的数组是使用不同的创建的Array对象。

这里有很多解决方案:

  1. 如果可能的话,为 IIS 启用 WebSocket http://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-websocket-protocol-support。从 IIS 8 和 Windows Server 2012 开始可以完成此操作。
  2. 如果 WebSocket 不可用,你可以指定 https://stackoverflow.com/questions/31578626/signalr-deserializes-my-objects-incorrectly-in-iis-7-5-and-edge-ie-foreverframe in the $.connection.hub.start()不应该使用 ForeverFrame 的参数,在 IE 和 Edge 上默认为 LongPolling。
  3. 您可以向 ForeverFrame 提供您自己的 JSON 解析器,并调用window.JSON:

    $.connection.hub.json = {
        parse: function(text, reviver) {
            console.log("Parsing JSON");
            return window.JSON.parse(text, reviver);
        },
        stringify: function(value, replacer, space) {
            return window.JSON.stringify(value, replacer, space);
        }
    };
    
  4. 而且,正如皮特的回答所建议的,你可以打电话Array.prototype.slice在接收到的对象上,将其转换为Array同一帧的。必须对从 SignalR 接收到的任何数组执行此操作,因此它不能像其他两个选项那样进行扩展。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 SignalR 在 IE 中缺少原型方法 的相关文章

  • 使用 Webpack 代理创建 React 应用程序中的 WebSockets

    我使用版本 3 1 2 2019 年 9 月 19 日 中的 Create React App 创建了我的 React 应用程序 我试图为 Web Socket 请求配置代理 但似乎当我使用代理时 未建立连接 我用过THIS https g
  • 为什么 TypeScript 混合了模块和原型模式?

    我正在查看此页面上 TypeScript 生成的 JS 代码 http www typescriptlang org Playground http www typescriptlang org Playground 基本上 要创建一个Gr
  • 网络驱动程序 | IE9 |设置自动下载文件

    我需要测试下载操作 我已经为 FF 和 Chrome 浏览器配置了远程网络驱动程序 可以自动下载文件 而无需任何提示和弹出窗口 但我找不到任何有用的信息 如何允许 IE9 自动下载文件 我尝试过的 找到任何可能的方法来配置驱动程序本身 什么
  • JavaScript:如何在 Internet Explorer 中模拟更改事件(委托)

    UPDATE 回顾 小提琴和赏金 这个问题并没有引起太多关注 所以我将花一些时间来解决这个问题 我知道我的答案和问题都过于冗长 这就是为什么我继续设置这把小提琴 http jsfiddle net vVA8N 在我看来 这是我目前必须用来接
  • 使用 javascript 在 IFrame 中打印 PDF 文件仅获取一页

    这是我打印 pdf 文件的代码 在这里 在打印时我只得到一页 我需要一个解决方案 function printPdf var ifr document getElementById frame1 PDF is completely load
  • IE9 中的 IE7/8 模式与实际运行 IE7/8 相比效果如何

    我试图确认这一点是出于工作目的 因此我们不需要单独的虚拟机在 IE7 和 IE8 中进行测试 我一直只是使用IE9 F12 中的开发者工具并更改浏览器模式和文档模式来进行IE7和IE8测试 这与 真实 IE7 和 IE8 中的实际测试相比如
  • Internet Explorer 的数组indexOf 实现

    有很多关于如何将 indexOf 实现放入数组原型中以便它可以在 Internet Explorer 下工作的解决方案 但是我偶然发现了一个问题 到目前为止我所看到的任何地方似乎都没有解决这个问题 使用非常一致的MDC 的实施 https
  • Fiddler 导致我的互联网访问停止工作

    我的计算机上安装了 Windows 8 1 并经常使用 Fiddler 捕获网络流量 然而 最近 当我打开 Fiddler 并让它捕获网络流量时 我的互联网连接中断了 我打开 IE 时收到的错误是 无法显示此页面 在 Chrome 中 我收
  • 添加或删除带有原型的类

    无法计算用于添加或删除基于单击函数的 img 元素 选定 的 css 类名 选定 的 PROTOTYPE 脚本 已为 Jquery 完成 但它必须在 Prototype 中 这让我发疯 无法使其适用于原型 我的原始代码是 Magento 商
  • 如何默认以 IE7 模式打开 Internet Explorer 9?

    我想将 IE 设置为始终以 IE7 模式打开 我主要在 Chrome 中进行开发 出于效率和 80 20 原则的目的 我假设 IE9 的外观和行为与 Chrome 基本相似 我认为如果某些东西在 IE7 中看起来和工作得足够好 大多数时候
  • 在 IE 上使用 CKEditor 插件获取选定的文本

    我为 CKEditor 制作了一个插件 但它依赖于当前选定的文本 在 FF 和 Chrome 中我可以使用 var selectedText editor getSelection getNative 但这在 IE 中不起作用 我只能得到
  • 使用信号器时会话超时

    我有一个网络应用程序 主要用于监控系统 它使用信号器从服务器 服务器推送 更新来刷新显示 该页面还有一些按钮 它们也使用相同的信号器连接将数据发送到服务器 问题是 signalr 使用单独的连接 因此即使它定期从服务器发送和接收数据 会话也
  • 如何在 IE 中使用 relatedTarget (或等效项)?

    显然 IE 11 有问题relatedTarget 例如blur事件 IE 有没有替代方法来获取relatedTarget 下面是一个在 IE 中产生错误的示例 https jsfiddle net rnyqy78m https jsfid
  • IE 测试器中的警报框

    IE Tester 没有控制台 并且该软件中的警报框似乎被忽略 这是预期的行为吗 如果是这样 如何使用这个工具调试 javascript 我安装了调试栏 但除了允许我查看 DOM 之外 它似乎没有做任何有用的事情 我需要能够在脚本执行期间检
  • 为什么 IE 不将

    我正在运行这个示例脚本 http jsfiddle net KsV2F 2 使用IE var select select var button button button click function var option
  • 如何在 IE9 中检测用户禁用了某个加载项?

    IE9 用户可以通过单击齿轮按钮并选择 管理加载项 来禁用加载项 例如浏览器帮助程序对象 我需要使用 JavaScript 检测给定的附加组件是否已以这种方式被禁用 我似乎无法找到错误处理程序的方法
  • asp.net/jQuery:使用 jQuery 将数据发布到弹出窗口 [IE]

    我正在尝试在 asp net 应用程序中使用 jQuery 将数据发布到弹出窗口 如果弹出窗口打开 我会收到三个错误 第一个错误是 Errror the value of the property is null or undefined
  • IE bug:具有不透明背景色的绝对定位元素

    我有一个绝对定位的 DIV 需要捕获 onclick 事件 事实证明 在 IE7 中 DIV 似乎没有诸如单击甚至光标之类的 足迹 例如 div width 200px height 200px position absolute bord
  • 如何使使用 css 调整大小的图像在 IE 中看起来不错?

    当使用 css 宽度 高度或属性宽度 高度缩放图像时 IE6 和 IE7 无法很好地缩放网页中的图像 我不确定它默认使用哪种算法 但这不好 在这些浏览器中缩放时 缩放图像会显示锯齿伪影 幸运的是 有一种方法可以通过简单的 css 规则强制
  • IE 中的 XPath 查询使用从零开始的索引,但 W3C 规范是从一开始的。我应该如何处理差异?

    问题 我正在转换目前仅适用于 Internet Explorer 的相对较大的 Javascript 代码 以便使其也适用于其他浏览器 由于代码广泛使用 XPath 我们做了一些兼容性功能以使事情变得更容易 function selectN

随机推荐