Использование jQuery с Windows 8 Metro JavaScript App вызывает ошибку безопасности
Поскольку это звучало как jQuery был вариантом для приложений Metro JavaScript, я начал с нетерпением ждать Windows 8 dev. Я установил Visual Studio 2012 Express RC и начал новый проект (как пустые, так и сетчатые шаблоны имеют одинаковую проблему).
Я сделал локальную копию jQuery 1.7.2 и добавил ее как ссылку script.
<!-- 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' A script попытался добавить динамический контент или элементы, ранее измененные динамически, которые могут быть небезопасными. Для например, используя свойство innerHTML для добавления script или искаженного 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?
Ответы
Ответ 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). И вы можете сделать некоторые основные манипуляции с DOM, используя пространство имен WinJS.Utilities
.
Вы должны дважды подумать об использовании jQuery для отложенных операций. Объект WinJS.Promise
используется во всех API-интерфейсах Metro для представления асинхронных действий, и вы в конечном итоге используете два подхода, сходных друг с другом.
Ответ 2
Вот ваш ответ
https://github.com/appendto/jquery-win8
Официальная библиотека jquery для окон 8
Ответ 3
Для чего это стоит, я портировал большую часть ядра jQuery, чтобы обернуть собственную библиотеку WinJS. Он легкий и обеспечивает практически все, что делает jQuery с добавлением некоторых плагинов для значков, уведомлений и т.д.
Это незавершенное производство, но я пытаюсь заставить некоторых людей присоединиться к веселью.
https://github.com/rmcvey/winjq
Быстрая запись (добавляется документация): http://practicaljs.com/jquery-in-windows-8-apps/
Ответ 4
После недавней конференции //Build/2012 и в этом разговоре рассказывается об использовании jQuery в Windows 8 Store Apps. В частности, они говорят о точном исключении script injection внутри innerHTML и рассказывают об обновлениях, сделанных в этом.
Компания AppendTo официально анонсировала jQuery для Windows 8 во время этого разговора. Он выглядит аккуратно из демонстрации, приведенной в разговоре в ссылке.
Они также говорят, что неплохо получить jQuery из CDN для приложений Windows 8 в локальном контексте!
Ответ 5
Шаблон динамического содержимого JavaScript на GitHub был создан и выпущен Microsoft Open Technologies для устранения этой ошибки. Он не был протестирован с помощью jQuery, но, скорее всего, решит вашу проблему. Ссылка на файл winstore-jscompat.js в начале вашего приложения перед запуском любых других сценариев, и вы больше не увидите эту ошибку.
Ответ 6
Я провел немного больше исследований и хотел прояснить пару вещей.
Ошибка, которую вы видите, находится в консоли JavaScript, а не в качестве фактического исключения. Код jQuery продолжает работать нормально. Это фактически то, что базовая система регистрирует, а не ошибка или исключение.
Нет причин для исправления jQuery или сделать что-либо еще - это шумный системный компонент, а не фактическая ошибка.
Ответ 7
Я написал довольно подробное объяснение того, как заставить jQuery работать с Windows 8 здесь
http://davidvoyles.wordpress.com/2013/09/23/hacking-jquery-to-work-in-windows-8/
Ответ 8
Если вы все еще нуждаетесь в этом, я пишу повторную реализацию объекта Deferred, найденного в jQuery.
После завершения он должен быть на 100% совместим с объектом jQuery Deferred. Сейчас это довольно полно, но требует некоторого тестирования.
См. this.
Надеюсь, это поможет!
Тем не менее, я думаю, что было бы неплохо научиться использовать реализацию Microsoft Promise вместо jQuery при работе с приложениями Windows 8.
Ответ 9
Мне удалось устранить проблему, найдя все места в 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)
Ответ 10
Я считаю, что это то же ограничение, что и политика безопасности контента (CSP). Этот конкретный случай был рассмотрен в jQuery 1.8.0. Остается ли проблема там?
https://github.com/jquery/jquery/commit/dc83072878ed9636c8158a014bd9fa4acc1ccce3
Ответ 11
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);