L’utilisation de jQuery avec Windows 8 Metro JavaScript App provoque une erreur de sécurité

Comme il semblait que jQuery était une option pour les applications Metro JavaScript , je commençais à attendre avec impatience Windows 8 dev. J’ai installé Visual Studio 2012 Express RC et lancé un nouveau projet (les modèles vides et les modèles de grid ont le même problème).

J’ai fait une copie locale de jQuery 1.7.2 et l’ai ajouté comme référence de script.

    

Malheureusement, dès que j’ai exécuté l’application résultante, une erreur de console est lancée:

HTML1701: Impossible d’append du contenu dynamic ‘a’ Un script a tenté d’injecter du contenu dynamic ou des éléments modifiés précédemment de manière dynamic, qui pourraient être dangereux. Par exemple, l’utilisation de la propriété innerHTML pour append un script ou un code HTML mal formé générera cette exception. Utilisez la méthode toStaticHTML pour filtrer le contenu dynamic ou créez explicitement des éléments et des atsortingbuts avec une méthode telle que createElement. Pour plus d’informations, voir http://go.microsoft.com/fwlink/?LinkID=247104 .

J’ai giflé un point d’arrêt dans une version non minifiée de jQuery et trouvé la ligne incriminée :

 div.innerHTML = " 
a";

Apparemment, le modèle de sécurité pour les applications Metro interdit de créer des éléments de cette manière . Cette erreur ne pose pas de problèmes immédiats à l’utilisateur, mais compte tenu de son emplacement, je crains que les tests de découverte des capacités de jQuery ne provoquent pas de problèmes.

Je veux absolument que jQuery $.Deferred à peu près tout facile. Je préférerais pouvoir utiliser le moteur de sélection et les systèmes de gestion des événements, mais je vivrais sans eux si nécessaire.

Comment peut-on obtenir la dernière version de jQuery avec le développement Metro?

Vous devez modifier la source jQuery pour que vous passiez la fonction MSApp.execUnsafeLocalFunction à MSApp.execUnsafeLocalFunction , ce qui désactive la vérification de contenu non sécurisée, comme ceci:

 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; }); 

Vous devez vous rappeler de supprimer la dernière paire de parenthèses – vous n’avez pas besoin d’une fonction auto- execUnsafeLocalFunction car execUnsafeLocalFunction exécute automatiquement la fonction à laquelle il est passé.

Je suggère qu’une meilleure approche consiste à utiliser les fonctionnalités WinJS – ceci inclut l’object WinJS.Promise comme alternative aux opérations différées (qui sont elles-mêmes une implémentation du modèle Promise). Et vous pouvez faire quelques manipulations de base en utilisant l’espace de noms WinJS.Utilities .

Vous devriez réfléchir à deux fois avant d’utiliser jQuery pour les opérations différées. L’object WinJS.Promise est utilisé dans les API Metro pour représenter des activités asynchrones et vous allez vous retrouver avec deux approches similaires mais différentes.

Pour ce que cela vaut, j’ai porté la majorité du kernel jQuery pour envelopper la bibliothèque WinJS native. Il est léger et fournit à peu près tout ce que fait jQuery avec l’ajout de certains plugins pour les badges, les notifications, etc.

C’est un travail en cours, mais j’essaie de faire participer certaines personnes à la fête.

https://github.com/rmcvey/winjq

Rédaction rapide (la documentation est ajoutée à): http://practicaljs.com/jquery-in-windows-8-apps/

Après la récente conférence // Build / 2012 et cette conférence parle de l’utilisation de jQuery dans Windows 8 Store Apps. Plus précisément, ils parlent de l’exception exacte de l’ injection de script dans innerHTML , et parlent des mises à jour effectuées dans ce script .

La société AppendTo a également dévoilé officiellement jQuery pour Windows 8 lors de cette conférence. Cela a l’air bien de la démonstration donnée dans la conversation dans le lien à propos de.

Ils disent aussi que ce n’est pas une bonne idée d’obtenir jQuery de CDN pour les applications Windows 8 dans le contexte local!

Le composant JavaScript Dynamic Content shim sur GitHub a été créé et publié par Microsoft Open Technologies pour résoudre cette erreur. Il n’a pas été testé avec jQuery mais résoudra probablement votre problème. Référencez le fichier winstore-jscompat.js au début de votre application avant que les autres scripts ne soient exécutés et vous ne devriez plus voir cette erreur.

J’ai fait un peu plus d’enquête et je voulais clarifier quelques points.

L’erreur que vous voyez est dans la console JavaScript, pas une exception réelle. Le code jQuery continue à fonctionner correctement . C’est en fait quelque chose que le système sous-jacent enregistre, pas une erreur ou une exception.

Il n’y a pas de raison de patcher jQuery ou de faire autre chose – c’est un composant système bruyant, pas une erreur réelle.

J’ai écrit une explication assez détaillée sur la façon de faire fonctionner jQuery avec Windows 8 ici http://davidvoyles.wordpress.com/2013/09/23/hacking-jquery-to-work-in-windows-8/

Si vous en avez encore besoin, j’écris une réimplémentation de l’object différé trouvé dans jQuery.

Une fois terminé, il devrait être compatible à 100% avec l’object différé de jQuery. En ce moment, c’est assez complet mais nécessite des tests.

Voir ça

J’espère que cela aidera!

Cela dit, je pense que ce devrait être une bonne idée d’apprendre à utiliser l’implémentation de Promise par Microsoft au lieu de jQuery lorsque vous travaillez sur des applications Windows 8.

Je crois que c’est la même ressortingction que celle imposée par la politique de sécurité du contenu (CSP). Ce cas spécifique a été traité dans jQuery 1.8.0. Est-ce que le problème existe toujours là?

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

jQuery lui-même n’a pas jeté de telles exceptions pour moi dans la dernière version tant que j’ai remplacé tout le code du formulaire, par exemple:

 $('') 

avec

 $(toStaticHTML('')) 

Notez que toutes les chaînes HTML ne sont pas considérées comme dangereuses, par exemple:

 $('') 

Ne jette aucune exception. Cependant, jQuery continue à afficher des exceptions si vous faites quelque chose du genre:

 var div = '

Ce qui précède n’est pas un exemple de bonnes pratiques d’utilisation de jQuery, mais certaines personnes le font pour que vous renconsortingez l’erreur. Notez que le code ci-dessus ne génère pas la même erreur que le tout premier extrait, mais renvoie l’erreur à l’intérieur de jQuery.append. Cette erreur est toujours corrigée par l’exécution de $(toStaticHTML(div)).appendTo(container);

J’ai été en mesure d’éliminer le problème en trouvant tous les endroits dans jQuery qui définissent innerHTML et encapsulent la valeur définie avec toStaticHTML() .

Donc, par exemple:

 div.innerHTML = " 
a";

devenu:

 div.innerHTML = toStaticHTML(" 
a");

Pour être sûr, j’ai également défini ceci juste avant la définition de jQuery, au cas où le fichier serait utilisé dans un navigateur normal:

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

Pour moi, cela semblait être le changement le plus sûr, même si cela nécessitait de réparer une douzaine d’endroits dans jQuery. (n’utilisez pas une instruction var avant le toStaticHTML)