web-dev-qa-db-fra.com

Comment échapper à une chaîne de code JavaScript dans un gestionnaire onClick?

Peut-être que je ne fais que trop penser à cela, mais j'ai du mal à comprendre ce qu'il est préférable d'utiliser avec une chaîne dans du code JavaScript dans le gestionnaire onClick d'un lien. Exemple:

<a href="#" onclick="SelectSurveyItem('<%itemid%>', '<%itemname%>'); return false;">Select</a>

<%itemid%> et <%itemname%> sont les endroits où la substitution de modèle se produit. Mon problème est que le nom de l'élément peut contenir n'importe quel caractère, y compris les guillemets simples et doubles. Actuellement, s'il contient des guillemets simples, le code JavaScript est cassé.

Ma première pensée a été d'utiliser la fonction du langage de modèle pour JavaScript en échappant le nom de l'élément, ce qui échappe simplement aux guillemets. Cela ne résoudra pas le cas de la chaîne contenant des guillemets doubles qui casse le code HTML du lien. Comment ce problème est-il normalement traité? Dois-je utiliser HTML pour échapper à l'intégralité du gestionnaire onClick?

Si tel est le cas, cela paraîtrait vraiment étrange puisque la fonction d'échappement du langage de template pour cela HTMLifierait également les parenthèses, les guillemets et les points-virgules ...

Ce lien est généré pour chaque résultat dans une page de résultats de recherche. Il est donc impossible de créer une méthode distincte à l'intérieur d'une balise JavaScript, car il me faudrait en générer une par résultat.

De plus, j'utilise un moteur de modélisation qui a été développé par la société pour laquelle je travaille. Les solutions spécifiques aux outils ne me seront d'aucune utilité.

63
rmeador

En JavaScript, vous pouvez coder des guillemets simples sous la forme "\ x27" et des guillemets doubles sous la forme "\ x22". Par conséquent, avec cette méthode, vous pouvez, une fois que vous vous trouvez à l'intérieur des guillemets (doubles ou simples) d'un littéral JavaScript, utiliser le\x27\x22 en toute impunité, sans craindre que des guillemets incorporés "se détachent" de votre chaîne. 

\ xXX est pour les caractères <127 et\uXXXX pour Unicode , donc armé de cette connaissance, vous pouvez créer une fonction robuste JSEncode pour tous les caractères sortant de la liste blanche habituelle.

Par exemple,

<a href="#" onclick="SelectSurveyItem('<% JSEncode(itemid) %>', '<% JSEncode(itemname) %>'); return false;">Select</a>
77
Duncan Smart

En fonction de la langue côté serveur, vous pouvez utiliser l’un des types suivants:

.NET 4.0

string result = System.Web.HttpUtility.JavaScriptStringEncode("jsString")

Java

import org.Apache.commons.lang.StringEscapeUtils;
...

String result = StringEscapeUtils.escapeJavaScript(jsString);

Python

import json
result = json.dumps(jsString)

PHP

$result = strtr($jsString, array('\\' => '\\\\', "'" => "\\'", '"' => '\\"', 
                                 "\r" => '\\r', "\n" => '\\n' ));

Rubis sur rails

<%= escape_javascript(jsString) %>
20
Vitalii Fedorenko

Utilisez des plages masquées, une pour chacun des paramètres <%itemid%> et <%itemname%>, et écrivez leurs valeurs à l'intérieur.

Par exemple, l'envergure de <%itemid%> devrait ressembler à <span id='itemid' style='display:none'><%itemid%></span> et dans la fonction javascript SelectSurveyItem pour sélectionner les arguments à partir de la innerHTML de ces étendues.

10
Shyam

Évitez d'utiliser des littéraux de chaîne dans votre code HTML et utilisez JavaScript pour lier des événements JavaScript.

Aussi, évitez 'href = #' à moins que vous vraiment sachiez ce que vous faites. Il casse tellement la facilité d'utilisation pour les médiateurs exigeants (ouvre-tabule).

<a id="tehbutton" href="somewhereToGoWithoutWorkingJavascript.com">Select</a>

Ma bibliothèque JavaScript de choix est justement jQuery:

<script type="text/javascript">//<!-- <![CDATA[
jQuery(function($){
   $("#tehbutton").click(function(){
        SelectSurveyItem('<%itemid%>', '<%itemname%>');
        return false;
   });
});
//]]>--></script>

Si vous rendez une liste de liens comme celle-ci, vous pouvez le faire:

<a id="link_1" href="foo">Bar</a>
<a id="link_2" href="foo2">Baz</a>

<script type="text/javascript">
   jQuery(function($){
        var l = [[1,'Bar'],[2,'Baz']];
        $(l).each(function(k,v){
           $("#link_" + v[0] ).click(function(){
                SelectSurveyItem(v[0],v[1]);
                return false;
           });
        });
   });
 </script>
9
Kent Fredric

Si vous utilisez un attribut HTML, vous devez coder en HTML (au minimum: > à &gt;< à &lt et " à &quot;), it et escape de guillemets simples (avec une barre oblique inverse) afin ils n'interfèrent pas avec vos citations en javascript. 

La meilleure façon de le faire est d'utiliser votre système de templates (en l'étendant si nécessaire), mais vous pouvez simplement créer quelques fonctions d'échappement et d'encodage et les enrouler autour de toutes les données qui y sont stockées.

Et oui, il est parfaitement valide (correct, même) d’écrire en HTML le contenu complet de vos attributs HTML, même s’ils contiennent du javascript.

8
Dan

Une autre solution intéressante pourrait être de faire ceci:

<a href="#" itemid="<%itemid%>" itemname="<%itemname%>" onclick="SelectSurveyItem(this.itemid, this.itemname); return false;">Select</a>

Vous pouvez ensuite utiliser un codage HTML standard sur les deux variables, sans avoir à vous soucier de la complication supplémentaire de la citation javascript.

Oui, cela crée un code HTML strictement non valide. Cependant est une technique valide, et tous les navigateurs modernes la prennent en charge.

Si c'était mon cas, j'irais probablement de l'avant avec ma première suggestion et je m'assurais que les valeurs sont codées en HTML et sans les guillemets simples.

3
Dan

Déclarez des fonctions séparées dans la section <head> et appelez celles de votre méthode onClick. Si vous en avez beaucoup, vous pouvez utiliser un schéma de dénomination qui les numérote ou passer un entier dans votre onClicks et avoir une grosse instruction switch dans la fonction. 

1
moonshadow

Utilisez la bibliothèque Microsoft Anti-XSS qui inclut un code JavaScript.

1
blowdart

Premièrement, ce serait plus simple si le gestionnaire onclick était configuré comme suit:

<a id="someLinkId"href="#">Select</a>
<script type="text/javascript">
  document.getElementById("someLinkId").onClick = 
   function() {
      SelectSurveyItem('<%itemid%>', '<%itemname%>'); return false;
    };

</script>

Ensuite, itemid et itemname doivent être échappés pour JavaScript (c'est-à-dire, " devient \", etc.).

Si vous utilisez Java côté serveur, vous pouvez jeter un coup d'œil à la classe StringEscapeUtils de common-lang de jakarta. Sinon, l'écriture de votre propre méthode 'escapeJavascript' ne devrait pas être trop longue.

1
Alexandre Victoor

J'ai aussi fait face à ce problème. J'ai créé un script pour convertir les guillemets simples en guillemets doubles échappés sans casser le code HTML.

function noQuote(text)
{
    var newtext = "";
    for (var i = 0; i < text.length; i++) {
        if (text[i] == "'") {
            newtext += "\"";
        }
        else {
            newtext += text[i];
        }
    }
    return newtext;
}
1
Starbuck Johnson

Tout bon moteur de gabarit digne de ce nom aura une fonction "citations d'échappement". Le nôtre (aussi de chez moi, où je travaille) a aussi une fonction pour échapper des guillemets au javascript. Dans les deux cas, la variable de modèle est alors simplement ajoutée avec _esc ou _js_esc, selon ce que vous voulez. Vous ne devriez jamais transmettre le contenu généré par l'utilisateur à un navigateur qui n'a pas été échappé, IMHO.

0
livingtech

Est-ce que les réponses ici sont que vous ne pouvez pas échapper des guillemets à l'aide de JavaScript et que vous devez commencer par des chaînes échappées?.

Donc. Il n’existe aucun moyen de JavaScript capable de gérer la chaîne 'Marge a déclaré: «Je dirais que c’était« à Peter »et vous avez besoin de nettoyer vos données avant de les proposer au script?

0
Steve Perks

J'ai rencontré le même problème et je l'ai résolu de manière délicate. Commencez par créer des variables globales, v1, v2 et v3. Et dans le onclick, envoyez un indicateur, 1, 2 ou 3 et dans le contrôle de fonction pour 1, 2, 3 pour mettre les v1, v2 et v3 comme:

onclick="myfun(1)"
onclick="myfun(2)"
onclick="myfun(3)"

function myfun(var)
{
    if (var ==1)
        alert(v1);

    if (var ==2)
        alert(v2);

    if (var ==3)
        alert(v3);
}
0
AhmedGamal