Maison  >  Article  >  interface Web  >  Comment lier dynamiquement du HTML

Comment lier dynamiquement du HTML

高洛峰
高洛峰original
2017-03-08 15:49:531242parcourir

Dans le développement Web front-end, nous rencontrons souvent le besoin de lier dynamiquement certaines chaînes HTML du backend ou d'épissage dynamique à l'affichage DOM de la page, en particulier dans les systèmes de gestion de contenu (abréviation CMS : Content Management System), de tels besoins sont partout.

Les lecteurs d'angular penseront certainement à ngBindHtml en premier. Oui, angulaire nous fournit cette instruction pour lier dynamiquement le HTML. Il liera le résultat de l'expression calculée au DOM en utilisant innerHTML. Toutefois, le problème n’est pas si simple. En sécurité Web, XSS (Cross-site scripting, script injection Attack) est une vulnérabilité de sécurité informatique typique dans les applications Web. Les attaques XSS font référence à l'injection de code client exécutable dans des pages Web et à leur exécution réussie par le navigateur pour atteindre l'objectif de l'attaque, formant ainsi une attaque XSS efficace. Une fois l'attaque réussie, elle peut obtenir certaines informations sensibles de l'utilisateur. expérience utilisateur, induisant les utilisateurs et d'autres comportements illégaux, parfois les attaques XSS sont combinées avec d'autres méthodes d'attaque, telles que les attaques par injection SQL sur les serveurs et les bases de données, le détournement de clics, le détournement de liens relatifs, etc. pour mettre en œuvre le phishing. et c'est aussi un web L'ennemi numéro un de la sécurité. Pour plus de problèmes de sécurité Web, veuillez vous référer au wiki https://en.wikipedia.org/wiki/Cross-site_scripting.

En angulaire, le contenu HTML ajouté n'est pas approuvé par défaut. Pour le contenu HTML ajouté, vous devez d'abord utiliser $sce.trustAsHtml pour indiquer à Angular qu'il s'agit d'un contenu HTML approuvé. Sinon, vous obtiendrez une erreur d'exception $sce:unsafe.

Error: [$sce:unsafe] Attempting to use an unsafe value in a safe context.

Ce qui suit est une démo qui lie un simple lien angulaire :

HTML :

<div ng-controller="DemoCtrl as demo">
    <div ng-bind-html="demo.html"></div>
</div>

JavaScript :

angular.module("com.ngbook.demo", [])
    .controller("DemoCtrl", ["$sce", function($sce) {
        var vm = this;

        var html = &#39;<p>hello <a href="https://angular.io/">angular</a></p>&#39;;
        vm.html = $sce.trustAsHtml(html);

        return vm;
    }]);

Pour Avec du HTML statique simple, ce problème est résolu. Mais pour le HTML complexe, la complexité fait ici référence aux modèles HTML avec des expressions et des instructions angulaires. Pour eux, nous espérons non seulement lier de grands écrans DOM, mais également espérer obtenir le puissant mécanisme de liaison bidirectionnelle d'Angular. ngBindHhtml ne sera pas associé à $scope pour la liaison bidirectionnelle. S'il existe ngClick, ngHref, ngSHow, ngHide et d'autres instructions angulaires en HTML, elles ne seront pas compilées. La formule ne sera pas mise à jour. Par exemple, si vous essayez de modifier le dernier lien en : ng-href="demo.link", le lien ne sera pas analysé et la chaîne HTML d'origine sera toujours visible dans le DOM.

Pour prendre effet, toutes les instructions angulaires doivent passer par la compilation. Compile contient un pré-lien et un post-lien, et est connecté à des comportements spécifiques avant de pouvoir fonctionner. Dans la plupart des cas, la compilation sera automatiquement compilée au démarrage d'Angular. Mais s'il s'agit d'un modèle ajouté dynamiquement, vous devez le compiler manuellement. Angular nous fournit le service $compile pour implémenter cette fonction. Ce qui suit est un exemple de compilation plus général :

HTML :

<body ng-controller="DemoCtrl as demo">
    <dy-compile html="{{demo.html}}">
    </dy-compile>
    <button ng-click="demo.change();">change</button>
</body>

JavaScript :

angular.module("com.ngbook.demo", [])
    .directive("dyCompile", ["$compile", function($compile) {
        return {
            replace: true,
            restrict: &#39;EA&#39;,
            link: function(scope, elm, iAttrs) {
                var DUMMY_SCOPE = {
                        $destroy: angular.noop
                    },
                    root = elm,
                    childScope,
                    destroyChildScope = function() {
                        (childScope || DUMMY_SCOPE).$destroy();
                    };

                iAttrs.$observe("html", function(html) {
                    if (html) {
                        destroyChildScope();
                        childScope = scope.$new(false);
                        var content = $compile(html)(childScope);
                        root.replaceWith(content);
                        root = content;
                    }

                    scope.$on("$destroy", destroyChildScope);
                });
            }
        };
    }])
    .controller("DemoCtrl", [function() {
        var vm = this;

        vm.html = &#39;<h2>hello : <a ng-href="{{demo.link}}">angular</a></h2>&#39;;

        vm.link = &#39;https://angular.io/&#39;;
        var i = 0;
        vm.change = function() {
            vm.html = &#39;<h3>change after : <a ng-href="{{demo.link}}">&#39; + (++i) + &#39;</a></h3>&#39;;
        };
    }]);

Une directive appelée dy-compile est créée ici en premier. surveillera les changements dans la valeur html de l'attribut de liaison. Lorsque le contenu html existe, il essaiera d'abord de créer une sous-portée, puis utilisera le service $compile pour connecter dynamiquement le html entrant et remplacer le nœud DOM actuel pour créer la sous-portée ici ; la raison de la portée est de détruire facilement la portée à chaque fois que le DOM est détruit, de supprimer la fonction d'observateur apportée par la compilation HTML et d'essayer de détruire la portée lorsque la dernière portée parent est détruite.

En raison de la compilation et de la connexion ci-dessus, l'instruction ngHref peut prendre effet. Voici juste une tentative de donner un exemple de module angulaire de compilation dynamique. Pour des méthodes d'implémentation spécifiques, veuillez vous référer à votre entreprise pour déclarer des directives spécifiques.


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn