将 jQuery 与 Windows 8 Metro JavaScript App 一起使用会导致安全错误

Posted

技术标签:

【中文标题】将 jQuery 与 Windows 8 Metro JavaScript App 一起使用会导致安全错误【英文标题】:Using jQuery with Windows 8 Metro JavaScript App causes security error 【发布时间】:2012-06-07 05:46:15 【问题描述】:

因为它听起来像jQuery was an option for Metro javascript apps,我开始期待 Windows 8 开发版。我安装了 Visual Studio 2012 Express RC 并开始了一个新项目(空模板和网格模板都有同样的问题)。

我制作了 jQuery 1.7.2 的本地副本并将其添加为脚本参考。

<!-- SomeTestApp references -->
<link href="/css/default.css" rel="stylesheet" />
<script src="/js/jquery-1.7.2.js"></script>
<script src="/js/default.js"></script>

不幸的是,一旦我运行生成的应用程序,它就会抛出一个控制台错误:

html1701:无法添加动态内容“a”脚本试图注入动态内容,或者 以前动态修改的元素,这可能是不安全的。为了 例如,使用 innerHTML 属性添加脚本或格式错误的 HTML 会产生这个异常。使用 toStaticHTML 方法进行过滤 动态内容,或显式创建元素和属性 方法,例如 createElement。有关详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkID=247104.

我在非缩小版的 jQuery 中打了一个断点,发现 the offending line:

div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";

显然,Metro 应用程序的安全模型forbids creating elements this way。这个错误不会给用户带来任何直接的问题,但考虑到它的位置,我担心它会导致 jQuery 中的功能发现测试失败,这是不应该的。

我绝对想要 jQuery $.Deferred 让一切变得更容易。我希望能够使用选择器引擎和事件处理系统,但如果必须的话,我宁愿不用它们。

如何让最新的 jQuery 与 Metro 开发完美配合?

【问题讨论】:

你是通过cdn加载jquery吗? 没有。这是本地 jQuery 代码执行中触发的错误。 顺便说一句,看起来我可以学习 new promise system 而不是 jQuery 的 $.Deferred jQuery 1.8 需要另外两项修改才能完美地与 Windows 8 一起工作。我写了一个Blogpost,其中涵盖了必要的更改,提供了一些背景信息并提供了 jQuery 1.8 的“修补”版本。 这是在 Windows 8 上使用 jQuery 的好资源:incloud.de/2012/08/windows-8-using-jquery-for-app-development 【参考方案1】:

您需要编辑 jQuery 源代码,以便将 jQuery.support 函数传递给 MSApp.execUnsafeLocalFunction,这将禁用不安全内容检查,如下所示:

jQuery.support = MSApp.execUnsafeLocalFunction(function() 

    var support,
        all,
        a,
        select,
        opt,
        input,
        fragment,
        tds,
        events,
        eventName,
        i,
        isSupported,
        div = document.createElement( "div" ),
        documentElement = document.documentElement;


    // lots of statements removed for brevity

    return support;
);

您需要记住删除最后一对括号 - 您不需要自执行函数,因为 execUnsafeLocalFunction 会自动执行它传递的函数。

我建议更好的方法是使用 WinJS 功能 - 这包括 WinJS.Promise 对象作为延迟操作的替代方案(它们本身是 Promise 模式的实现)。并且您可以使用 WinJS.Utilities 命名空间进行一些基本的 DOM 操作。

您应该三思而后行使用 jQuery 进行延迟操作。 WinJS.Promise 对象在整个 Metro API 中用于表示异步活动,您最终将使用两种相似但不同的方法。

【讨论】:

太棒了,这也困扰着我,修复工作完美。如果有人不介意这样做或不想弄乱 jQuery 源代码,这是我刚刚为自己创建的缩小版本:pastebin.com/0NC6XBFp. 作为一个数据点,jQuery 1.7.1 不会导致这个错误,它是新的,在 1.7.2 中发生了一些变化。 这无疑解释了所有关于在 Metro 中使用 jQuery 的博客文章,没有人遇到任何问题。它们大多是在 VS12 处于开发预览阶段(2011 年 9 月 16 日发布)时编写的,在 jQuery 1.7.2(2012 年 3 月 21 日发布)之前。 奇怪 - 我刚刚尝试了 Win8 和 jQuery 1.7.2 的新发布预览版,一切正常,没有安全错误。这里发生了一些奇怪的事情...... Adam,您遇到的是第一次机会异常还是未处理的异常?如果您在调试器的对话框中点击“继续”,应用程序会死掉还是继续运行?如果它继续运行,它实际上不是问题,它只是一个已处理的异常。如果应用程序死了,那么就会发生其他事情。【参考方案2】:

这是你的答案

https://github.com/appendto/jquery-win8

适用于 windows 8 的官方 jquery 库

【讨论】:

该项目已“终止”,因为它的作者说问题已由 jQuery 2.0 修复;但是 jQuery 2.1.0 和 VisualStudio 2013 仍然会出现问题... 事实上 jQuery 2.0.2 不会出现问题,所以 2.0.2 和 2.1.0 之间似乎存在回归 这个问题在 jQuery 2.2.4 和 3.1.0 中仍然存在,在 WP8 应用程序上不能进行 append() 操作。【参考方案3】:

不管怎样,我已经移植了大部分 jQuery 核心来包装原生 WinJS 库。它是轻量级的,几乎提供了 jQuery 所做的一切,并添加了一些用于徽章、通知等的插件。

这是一项正在进行的工作,但我正在努力让一些人加入其中。

https://github.com/rmcvey/winjq

快速撰写(正在添加文档):http://practicaljs.com/jquery-in-windows-8-apps/

【讨论】:

很棒的图书馆,希望你继续努力:) 是的,我将它用于 Answers.com Windows 8 应用程序;您对图书馆有什么具体问题吗?【参考方案4】:

在最近的 //Build/ 2012 会议之后,this talk 谈到了在 Windows 8 应用商店应用程序中使用 jQuery。具体来说,他们在 innerHTML 中讨论了 脚本注入 的确切例外,并讨论了其中所做的更新。

公司 AppendTo 在那次谈话中也正式公布了jQuery for Windows 8。从链接中的演讲中给出的演示来看,它看起来很整洁。

他们还说,在本地上下文中从 CDN 为 Windows 8 应用程序获取 jQuery 不是一个好主意!

【讨论】:

完全正确——来自 CDN 的 jQuery 将不起作用,因为它会引发错误。您需要下载最新版本并将其存储在本地以供您的项目使用。【参考方案5】:

GitHub 上的 JavaScript Dynamic Content shim 由 Microsoft Open Technologies 创建并发布,以解决此错误。它尚未使用 jQuery 进行测试,但很可能会解决您的问题。在运行任何其他脚本之前,请在应用程序的开头引用 winstore-jscompat.js 文件,您应该不会再看到此错误。

【讨论】:

谢谢。这适用于 AngularJS,所以我认为它也适用于 jQuery。 谢谢!!如果可以的话,我会给你的答案投票 10 次,这确实是 Windows 问题的最终解决方案。现在我可以正常使用jQuery 2.x了。我浪费了几个小时四处寻找解决方案,谢谢。我现在就给你投票。【参考方案6】:

我做了更多调查,想澄清一些事情。

您看到的错误是在 JavaScript 控制台中,而不是实际的异常。 jQuery 代码继续运行很好。这实际上是底层系统正在记录的内容,而不是错误或异常。

没有理由修补 jQuery 或做任何其他事情 - 这是一个嘈杂的系统组件,而不是实际错误。

【讨论】:

我的应用强制在尝试忽略此错误消息时关闭。 你在哪里看到这个 - 你是在第一次加载 jquery .js 文件时得到它,还是因为你正在做的事情? 我的应用在“噪音”下运行良好,但我想知道这是否会让代码审查者从 Windows 8 应用商店拒绝你的应用。【参考方案7】:

我在这里写了一个关于如何让 jQuery 与 Windows 8 一起工作的非常详细的解释 http://davidvoyles.wordpress.com/2013/09/23/hacking-jquery-to-work-in-windows-8/

【讨论】:

我不久前移动了我的网站,我猜它破坏了链接。这是新的:davevoyles.azurewebsites.net/…【参考方案8】:

如果您仍然需要它,我正在编写 jQuery 中的 Deferred 对象的重新实现。

一旦完成,它应该与 jQuery 的 Deferred 对象 100% 兼容。现在它已经很完整了,但需要一些测试。

见this。

希望这会有所帮助!

也就是说,我认为在处理 Windows 8 应用程序时,学习如何使用 Microsoft 的 Promise 实现而不是 jQuery 应该是一个好主意。

【讨论】:

【参考方案9】:

我相信这与内容安全策略 (CSP) 施加的限制相同。 jQuery 1.8.0 解决了该特定情况。问题是否仍然存在?

https://github.com/jquery/jquery/commit/dc83072878ed9636c8158a014bd9fa4acc1ccce3

【讨论】:

是的,VisualStudio 13 和 jQuery 2.1.0 仍然存在问题 你向bugs.jquery.com举报了吗?请务必对您所看到的问题进行清晰的解释,而不仅仅是指向此页面的指针,因为它是旧的并且指的是旧问题。【参考方案10】:

jQuery 本身并没有在最新版本中为我抛出此类异常,只要我替换了表单的所有代码,例如:

$('<input type="button" value="Press Me" />')

$(toStaticHTML('<input type="button" value="Press Me" />'))

请注意,并非所有 HTML 字符串都被认为是不安全的,例如:

$('<span></span>')

不抛出任何异常。但是,如果您执行此类操作,jQuery 仍然会在追加时引发异常:

var div = '<div class="' + classesToApply + '"';
div += attrToAdd;
div += '</div>';

$(div).appendTo(container);

以上不是使用 jQuery 的良好实践示例,但仍有一些人这样做,因此您可能会遇到错误。请注意,上面的代码不会产生与第一个 sn-p 相同的错误,而是在 jQuery.append 中引发错误。通过执行$(toStaticHTML(div)).appendTo(container);仍然可以修复此错误

【讨论】:

【参考方案11】:

我能够通过在 jQuery 中找到所有设置 innerHTML 的位置并用 toStaticHTML() 包装设置的值来消除这个问题。

所以,例如:

div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";

成为:

div.innerHTML = toStaticHTML("   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>");

为了安全起见,我也在定义 jQuery 之前定义了这个,以防文件在普通浏览器中使用:

window.toStaticHTML = window.toStaticHTML || function (s)  return s; ;

对我来说,这似乎是最安全的更改,尽管它需要在 jQuery 中修补十几个地方。 (不要在 toStaticHTML 之前使用 var 语句)

【讨论】:

谨慎使用这种方法,因为toStaticHTML 可能会彻底改变您的字符串。例如,在第一个示例中,虽然您以&lt;link/&gt; 标记开始,但在通过toStaticHTML 之后,您将不再拥有该标记。其他被删除的内容包括 HTML5 数据属性。 同意。我们尝试了这种方法。但它从我们试图传递的标签中剥离了所有数据。没用。

以上是关于将 jQuery 与 Windows 8 Metro JavaScript App 一起使用会导致安全错误的主要内容,如果未能解决你的问题,请参考以下文章

jQuery Mobile-Phonegap:Windows 8 横向模式下的页脚对齐问题

discuz教程:discuz模板js与jQuery冲突的解决方案

jQuery Virtual Keyboard 插件在 Windows 8 触摸设备上插入相同的字符两次

Manjaro 与 Windows 双系统时间相差8小时

jQuery Mobile无法在PhoneGap Windows Phone 8中运行

jQuery 在 Windows Phone 8 手机间隙应用程序中不能很好地渲染角落