Использование jQuery с приложением Windows 8 Metro JavaScript вызывает ошибку безопасности

Поскольку казалось, что 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-разработкой?


person patridge    schedule 02.06.2012    source источник
comment
Вы загружаете jquery через cdn?   -  person lucuma    schedule 02.06.2012
comment
Нет. Это ошибка, вызванная выполнением локального кода jQuery.   -  person patridge    schedule 02.06.2012
comment
Кстати, похоже, я могу узнать новое обещание system вместо $.Deferred jQuery.   -  person patridge    schedule 02.06.2012
comment
jQuery 1.8 требует еще двух модификаций для безупречной работы с Windows 8. Я написал сообщение в блоге, который охватывает необходимые изменения, дает некоторую справочную информацию и предоставляет исправленную версию jQuery 1.8.   -  person David Müller    schedule 28.08.2012
comment
Вот хороший ресурс по использованию jQuery в Windows 8: incloud.de/2012/08/windows-8-using-jquery-for-app-development   -  person Nate Radebaugh    schedule 02.11.2012
comment
Для решения этой проблемы используйте следующее: github.com/Microsoft/winstore-jscompat   -  person Dilhan Jayathilake    schedule 27.10.2016


Ответы (11)


Вам нужно отредактировать исходный код 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 используется во всех API-интерфейсах Metro для представления асинхронных действий, и в конечном итоге вы будете использовать два похожих, но разных подхода.

person Adam Freeman    schedule 02.06.2012
comment
Круто, это тоже беспокоило меня, и исправление сработало отлично. Если кто-то не хочет этого делать или не хочет возиться с исходным кодом jQuery, вот уменьшенная версия, которую я только что создал для себя: pastebin.com/0NC6XBFp. - person Zac Seth; 02.06.2012
comment
Как точка данных, jQuery 1.7.1 не вызывает эту ошибку, это новое с чем-то, что изменилось в 1.7.2. - person Chris Tavares; 04.06.2012
comment
Это, безусловно, объясняет все сообщения в блогах об использовании jQuery с Metro, и ни у кого не возникло проблем. В основном они были написаны, когда VS12 был в предварительной версии для разработчиков (выпущен 16 сентября 2011 г.), до jQuery 1.7.2 (выпущен 21 марта 2012 г.). - person patridge; 06.06.2012
comment
Странно - я только что попробовал с новой версией Preview для Win8 и jQuery 1.7.2, и все просто сработало, без ошибок безопасности. Здесь происходит что-то странное... - person Chris Tavares; 06.06.2012
comment
Адам, вы получаете первое случайное исключение или необработанное исключение? Если вы нажмете «Продолжить» в диалоговом окне отладчика, приложение умрет или продолжит работу? Если он продолжает работать, на самом деле это не проблема, это просто обработанное исключение. Если приложение умирает, то происходит что-то еще. - person Chris Tavares; 12.06.2012
comment
Я получаю это как с jQuery 1.7.1, так и с 1.7.2 (уменьшенным) с VS2012RC. Мне даже не нужно нигде использовать jQuery, чтобы увидеть ошибку. Он отображается в консоли JavaScript, просто включив скрипт src=jquery в default.html. - person Don Smith; 22.06.2012
comment
При использовании jQuery 1.8 вам необходимо применить изменения к двум другим частям jQuery, см. мой ответ здесь: stackoverflow .com/a/12161279/623400 - person David Müller; 28.08.2012
comment
@ Зак Просто чтобы ты знал, ты классный. - person wtsang02; 02.04.2013
comment
Требуется ли это исправление в версии jQuery 2.0+? - person Dave Voyles; 23.08.2013

Вот твой ответ

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

Его официальная библиотека jquery для Windows 8

person Nikhil Ranjan    schedule 13.11.2012
comment
Проект закрыт, потому что его авторы говорят, что проблема была устранена в jQuery 2.0; однако проблема все еще возникает с jQuery 2.1.0 и VisualStudio 2013... - person Bambax; 07.02.2014
comment
На самом деле проблема не возникает с jQuery 2.0.2, поэтому между 2.0.2 и 2.1.0 наблюдается регресс. - person Bambax; 07.02.2014
comment
Проблема сохраняется в jQuery 2.2.4 и 3.1.0, операции append() невозможны в приложениях WP8. - person andreszs; 15.08.2016

Что бы это ни стоило, я перенес большую часть ядра jQuery, чтобы обернуть нативную библиотеку WinJS. Он легкий и предоставляет почти все, что делает jQuery, с добавлением некоторых плагинов для значков, уведомлений и т. д.

Работа продолжается, но я пытаюсь привлечь людей к веселью.

https://github.com/rmcvey/winjq

Краткое описание (документация добавляется к): http://practicaljs.com/jquery-in-windows-8-apps/

person Rob M.    schedule 31.08.2012
comment
Отличная библиотека, надеюсь, вы так держать :) - person travega; 30.01.2013
comment
Да, я использовал его для приложения Answers.com для Windows 8; у вас есть конкретные проблемы с библиотекой? - person Rob M.; 12.06.2013

После недавней конференции //Build/ 2012 и этого доклада об использовании jQuery в приложениях Магазина Windows 8. В частности, они говорят о точном исключении внедрения скрипта внутри innerHTML и говорят об обновлениях, сделанных в этом.

Во время этого выступления компания AppendTo также официально представила jQuery для Windows 8. Это выглядит аккуратно из демонстрации, приведенной в разговоре по ссылке.

Они также говорят, что не рекомендуется получать jQuery из CDN для приложений Windows 8 в локальном контексте!

person Sagar Sane    schedule 07.11.2012
comment
Точно -- jQuery из CDN работать не будет, так как выдает ошибку. Вам нужно будет загрузить последнюю версию и сохранить ее локально для своего проекта. - person Dave Voyles; 23.08.2013

Для устранения этой ошибки Microsoft Open Technologies создала и выпустила оболочку динамического содержимого JavaScript на GitHub. Он не тестировался с jQuery, но, скорее всего, решит вашу проблему. Ссылайтесь на файл winstore-jscompat.js в начале вашего приложения перед запуском любых других сценариев, и вы больше не должны видеть эту ошибку.

person buildwinjs    schedule 19.08.2014
comment
Спасибо. Это правильно работает с AngularJS, поэтому я предполагаю, что это также будет работать с jQuery. - person dwettstein; 29.07.2015
comment
Спасибо!! Я бы проголосовал за ваш ответ 10 раз, если бы мог, это действительно окончательное решение проблемы с Windows. Теперь я могу нормально использовать jQuery 2.x. Я потратил часы на поиски решения, спасибо. Я сейчас проголосую за вас. - person andreszs; 15.08.2016

Я провел небольшое расследование и хотел уточнить пару вещей.

Ошибка, которую вы видите, находится в консоли JavaScript, а не в реальном исключении. Код jQuery продолжает работать прекрасно. На самом деле это то, что регистрирует базовая система, а не ошибка или исключение.

Нет причин исправлять jQuery или делать что-то еще - это шумный системный компонент, а не фактическая ошибка.

person Chris Tavares    schedule 12.06.2012
comment
Мое приложение принудительно закрывается при попытке игнорировать это сообщение об ошибке. - person Frank Sposaro; 18.09.2012
comment
Где вы это видите - вы получаете это при первой загрузке файла jquery .js или это результат того, что вы на самом деле делаете? - person Chris Tavares; 18.09.2012
comment
Мое приложение отлично работает с шумом, но мне интересно, не отклонит ли это ваше приложение из магазина приложений Windows 8 рецензентами кода. - person user785179; 03.01.2013

Я написал довольно подробное объяснение того, как заставить jQuery работать с Windows 8 здесь http://davidvoyles.wordpress.com/2013/09/23/hacking-jquery-to-work-in-windows-8/

person Dave Voyles    schedule 23.09.2013
comment
Я переместил свой сайт некоторое время назад, я думаю, он сломал ссылку. Вот новый: davevoyles.azurewebsites.net/< /а> - person Dave Voyles; 08.02.2014

Если вам это все еще нужно, я пишу повторную реализацию объекта Deferred, найденного в jQuery.

После завершения он должен быть на 100% совместим с объектом Deferred jQuery. На данный момент он полностью завершен, но нуждается в тестировании.

См. это.

Надеюсь, это поможет!

Тем не менее, я думаю, что было бы неплохо научиться использовать реализацию Microsoft Promise вместо jQuery при работе с приложениями для Windows 8.

person Nicolas Ramz    schedule 15.06.2012

Я считаю, что это то же ограничение, что и политика безопасности контента (CSP). Этот конкретный случай был рассмотрен в jQuery 1.8.0. Проблема все еще возникает там?

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

person Dave Methvin    schedule 11.08.2012
comment
Да, проблема все еще возникает с VisualStudio 13 и jQuery 2.1.0. - person Bambax; 07.02.2014
comment
Вы сообщили об этом на bugs.jquery.com? Обязательно опубликуйте четкое объяснение проблемы, которую вы видите, а не просто указатель на эту страницу, поскольку она устарела и относится к старой проблеме. - person Dave Methvin; 08.02.2014

Сам 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);

person Konstantin Dinev    schedule 20.08.2012

Я смог устранить проблему, найдя все места в 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. (не используйте оператор var перед toStaticHTML)

person fpintos    schedule 10.08.2012
comment
Будьте осторожны с этим подходом, так как toStaticHTML может радикально изменить вашу строку. Например, в первом примере, хотя вы начали с тега <link/>, после прохождения через toStaticHTML у вас его больше не будет. Другие вещи, которые удаляются, включают атрибуты данных HTML5. - person Sampson; 07.10.2012
comment
Согласованный. Мы попробовали этот подход. но он удалил все данные из тегов, которые мы пытались передать. Бесполезный. - person Dave Voyles; 12.06.2013