44

因为听起来jQuery 是 Metro JavaScript 应用程序的一个选项,所以我开始期待 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 中打了一个断点,发现了有问题的行

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

显然,Metro 应用程序的安全模型禁止以这种方式创建元素。这个错误不会给用户带来任何直接的问题,但考虑到它的位置,我担心它会导致 jQuery 中的功能发现测试失败,这是不应该的。

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

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

4

11 回答 11

33

您需要编辑 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 模式的实现)。您可以使用命名空间进行一些基本的 DOM 操作WinJS.Utilities

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

于 2012-06-02T12:46:01.100 回答
8

这是你的答案

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

其适用于 windows 8 的官方 jquery 库

于 2012-11-13T14:26:54.843 回答
7

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

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

https://github.com/rmcvey/winjq

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

于 2012-08-31T17:44:17.700 回答
7

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

在那次演讲中,AppendTo公司还正式推出了适用于 Windows 8 的 jQuery 。从链接中的演讲中给出的演示来看,它看起来很整洁。

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

于 2012-11-07T04:31:27.560 回答
6

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

于 2014-08-19T18:38:53.350 回答
2

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

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

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

于 2012-06-12T19:54:10.877 回答
1

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

于 2013-09-23T20:56:58.497 回答
0

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

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

看到这个

希望这会有所帮助!

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

于 2012-06-15T13:49:52.653 回答
0

我能够通过在 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 语句)

于 2012-08-10T22:05:19.907 回答
0

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

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

于 2012-08-11T01:53:20.547 回答
0

只要我替换了表单的所有代码,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 的良好实践示例,但仍有一些人这样做,因此您可能会遇到错误。请注意,上面的代码不会产生与第一个片段相同的错误,而是在 jQuery.append 中引发错误。此错误仍然通过执行修复$(toStaticHTML(div)).appendTo(container);

于 2012-08-20T09:10:40.373 回答