web-dev-qa-db-fra.com

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

Étant donné que cela ressemblait à jQuery était une option pour les applications Metro JavaScript , je commençais à envisager Windows 8 dev. J'ai installé Visual Studio 2012 Express RC et démarré un nouveau projet (les modèles vides et les modèles de grille ont le même problème).

J'ai fait une copie locale de jQuery 1.7.2 et l'ajoutée en tant que référence de 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>

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

HTML1701: Impossible d'ajouter du contenu dynamique 'a' Un script a tenté d'injecter du contenu dynamique ou éléments précédemment modifiés dynamiquement, cela pourrait être dangereux. Pour Par exemple, en utilisant la propriété innerHTML pour ajouter un script ou un HTML mal formé va générer cette exception. Utilisez la méthode toStaticHTML pour filtrer contenu dynamique, ou créer explicitement des éléments et des attributs avec un 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 j'ai trouvé la ligne incriminée :

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

Apparemment, le modèle de sécurité pour les applications Metro interdit de créer des éléments de cette façon . Cette erreur ne cause pas de problèmes immédiats pour l'utilisateur, mais compte tenu de son emplacement, je crains que cela ne provoque des tests de découverte des fonctionnalités dans jQuery.

Je veux vraiment jQuery $.Deferred pour tout simplifier. Je préférerais pouvoir utiliser le moteur de sélecteur et les systèmes de gestion des événements, mais je vivrais sans eux si je devais le faire.

Comment obtenir le dernier jQuery pour bien jouer avec le développement de Metro?

44
patridge

Vous devez modifier la source jQuery afin de passer la fonction jQuery.support à MSApp.execUnsafeLocalFunction, ce qui désactive la vérification du contenu non sécurisé, 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;
});

N'oubliez pas de supprimer la dernière paire de parenthèses - vous n'avez pas besoin d'une fonction à exécution automatique, car execUnsafeLocalFunction exécute automatiquement la fonction à laquelle elle est transmise.

Je suggère qu'une meilleure approche consiste à utiliser les fonctionnalités de WinJS - cela inclut l'objet 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 effectuer quelques manipulations DOM 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'objet WinJS.Promise est utilisé dans les API Metro pour représenter les activités asynchrones. Vous utiliserez deux approches similaires mais différentes.

33
Adam Freeman

Voici votre réponse

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

Sa bibliothèque officielle jQuery pour Windows 8

8
Nikhil Ranjan

Pour ce que cela vaut, j'ai porté la majorité du noyau jQuery pour envelopper la bibliothèque native WinJS. Il est léger et fournit à peu près tout ce que jQuery fait avec l’ajout de 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 en train d'être ajoutée à): http://practicaljs.com/jquery-in-windows-8-apps/

7
Rob M.

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

La société AppendTo a également officiellement dévoilé jQuery pour Windows 8 au cours de cet entretien. Cela semble bien de la démonstration donnée dans la discussion sur le lien.

Ils disent également que ce n’est pas une bonne idée d’obtenir jQuery à partir d’applications CDN for Windows 8 dans un contexte local!

7
Sagar Sane

Le contenu dynamique JavaScript shim sur GitHub a été créé et publié par Microsoft Open Technologies pour corriger cette erreur. Cela n’a pas été testé avec jQuery mais cela résoudra probablement votre problème. Référencez le fichier winstore-jscompat.js au début de votre application avant d'exécuter d'autres scripts et ne devriez plus voir cette erreur. 

6
buildwinjs

J'ai fait un peu plus d'enquêtes 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 de s'exécuter très bien . C'est en fait quelque chose que le système sous-jacent enregistre, pas une erreur ou une exception.

Il n'y a aucune raison de corriger jQuery ou de faire autre chose - c'est un composant système bruyant, pas une erreur réelle.

2
Chris Tavares

Je pense que c'est la même restriction 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 persiste là?

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

0
Dave Methvin

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 de la forme, par exemple:

$('<input type="button" value="Press Me" />')

avec

$(toStaticHTML('<input type="button" value="Press Me" />'))

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

$('<span></span>')

Ne jette aucune exception. Cependant, jQuery lève toujours des exceptions sur append si vous faites quelque chose du genre:

var div = '<div class="' + classesToApply + '"';
div += attrToAdd;
div += '</div>';

$(div).appendTo(container);

Ce qui précède n’est pas un exemple de bonnes pratiques d’utilisation de jQuery, mais certaines personnes le font de sorte que vous pouvez rencontrer 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 via l'exécution de $(toStaticHTML(div)).appendTo(container);

0
Konstantin Dinev

Si vous en avez toujours besoin, j'écris une réimplémentation de l'objet Deferred trouvé dans jQuery.

Une fois terminé, il devrait être compatible à 100% avec l'objet différé de jQuery. Pour le moment, il est assez complet mais nécessite quelques tests.

Voir this .

J'espère que cela aidera!

Cela dit, je pense que ce serait une bonne idée d'apprendre à utiliser l'implémentation Promise de Microsoft au lieu de jQuery lors de l'utilisation d'applications Windows 8.

0
Nicolas Ramz

J'ai pu éliminer le problème en trouvant dans jQuery tous les emplacements définissant innerHTML et en encapsulant la valeur définie avec toStaticHTML().

Donc, par exemple:

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

est devenu:

div.innerHTML = toStaticHTML("   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>");

Par sécurité, j’ai également défini cela 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 corriger une douzaine d'endroits dans jQuery .

0
fpintos