将 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
可能会彻底改变您的字符串。例如,在第一个示例中,虽然您以<link/>
标记开始,但在通过toStaticHTML
之后,您将不再拥有该标记。其他被删除的内容包括 HTML5 数据属性。
同意。我们尝试了这种方法。但它从我们试图传递的标签中剥离了所有数据。没用。以上是关于将 jQuery 与 Windows 8 Metro JavaScript App 一起使用会导致安全错误的主要内容,如果未能解决你的问题,请参考以下文章
jQuery Mobile-Phonegap:Windows 8 横向模式下的页脚对齐问题
discuz教程:discuz模板js与jQuery冲突的解决方案
jQuery Virtual Keyboard 插件在 Windows 8 触摸设备上插入相同的字符两次