2008-09-18 12 views
61

Vielleicht denke ich gerade darüber zu hart, aber ich habe ein Problem herauszufinden, was zu einer Zeichenfolge in einigen JavaScript-Code in einem onClick-Handler-Link zu verwenden. Beispiel:Wie kann ich eine Zeichenfolge innerhalb von JavaScript-Code in einem onClick-Handler umgehen?

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

Die <%itemid%> und <%itemname%> sind, wo Template Substitution auftritt. Mein Problem ist, dass der Elementname ein beliebiges Zeichen enthalten kann, einschließlich einfacher und doppelter Anführungszeichen. Derzeit, wenn es einfache Anführungszeichen enthält, bricht es den JavaScript-Code.

Mein erster Gedanke war, die Funktion der Template-Sprache zu verwenden, um den Item-Namen, der nur den Anführungszeichen entgeht, zu JavaScript zu machen. Das wird die Groß- und Kleinschreibung der Zeichenfolge, die doppelte Anführungszeichen enthält, nicht beheben, wodurch der HTML-Code der Verknüpfung unterbrochen wird. Wie wird dieses Problem normalerweise behandelt? Muss ich den gesamten onClick-Handler HTML-escapen?

Wenn ja, das würde aussehen wirklich seltsam, da die Escape-Funktion der Template-Sprache für die auch die Klammern, Zitate und Semikolons htmlify würde ...

Dieser Link erzeugt in einer Suchergebnisseite für jedes Ergebnis wird Daher ist es nicht möglich, eine separate Methode innerhalb eines JavaScript-Tags zu erstellen, da ich pro Ergebnis eine eigene Methode erstellen müsste.

Außerdem verwende ich eine Template-Engine, die bei der Firma, für die ich arbeite, selbst entwickelt wurde, so dass Toolkit-spezifische Lösungen für mich keinen Nutzen haben werden.

Antwort

75

In JavaScript können Sie einfache Anführungszeichen als "\ x27" und doppelte Anführungszeichen als "\ x22" kodieren. Daher können Sie mit dieser Methode, sobald Sie sich innerhalb der (doppelten oder einzelnen) Anführungszeichen eines JavaScript-String-Literals befinden, ungestraft das \ x27 \ x22 verwenden, ohne befürchten zu müssen, dass eingebettete Anführungszeichen Ihren String "durchbrechen".

\ xXX ist für Zeichen < 127 und \ uXXXX für Unicode, so bewaffnet mit diesem Wissen können Sie eine robuste JSEncode Funktion für alle Charaktere erstellen, die aus der üblichen weißen Liste sind.

Zum Beispiel

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

Sie gespeichert meine tatsächlichen und einige meiner zukünftigen Tage – Krekkon

1

Deklarieren Sie separate Funktionen im Abschnitt <head> und rufen Sie diese in Ihrer onClick-Methode auf. Wenn Sie Lose haben, können Sie ein Benennungsschema verwenden, das sie nummeriert, oder eine Ganzzahl in Ihren onClicks übergeben und eine große fat switch-Anweisung in der Funktion haben.

8

Wenn es in ein HTML-Attribut gehen, müssen Sie sowohl HTML-Codierung (als Minimum: >-&gt;<-&lt und " zu &quot;) es, und Apostrophe (mit einem Backslash) so stören sie nicht dein Javascript, das zitiert.

Der beste Weg, es zu tun ist mit Ihrem Templating-System (erweitern Sie es, falls erforderlich), aber Sie könnten einfach ein paar Flucht/Encoding-Funktionen und wickeln sie beide um alle Daten, die dort gehen.

Und ja, es ist absolut gültig (korrekt, sogar) zu HTML-Escape den gesamten Inhalt Ihrer HTML-Attribute, auch wenn sie Javascript enthalten.

1

Erstens wäre es einfacher, wenn die Onclick-Handler auf diese Weise eingestellt wurde:

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

</script> 

Dann itemid und itemname müssen JavaScript zu entkommen (das heißt, " wird \", etc.).

Wenn Sie Java auf der Serverseite verwenden, können Sie sich die Klasse StringEscapeUtils von jakarta's common-lang ansehen. Ansonsten sollte es nicht zu lange dauern, um eine eigene 'escapeJavascript' Methode zu schreiben.

9

Versuchen Sie, Zeichenfolgenliterale in Ihrem HTML zu vermeiden und verwenden Sie JavaScript, um JavaScript-Ereignisse zu binden.

Vermeiden Sie auch 'href = #', außer Sie wirklich wissen, was Sie tun. Es bricht so viel Usability für zwanghafte Middleclickers (Tab Opener).

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

Mein JavaScript-Bibliothek der Wahl passiert einfach jQuery sein:

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

Wenn Sie eine Liste von Links wie das geschehen zu machen, können Sie dies tun wollen:

<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> 
3

Eine andere interessante Lösung könnte sein, dies zu tun:

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

Dann können Sie eine Standard-HTML-Codierung für beide Variablen verwenden, ohne sich um die zusätzliche Komplikation der JavaScript-Zitate kümmern zu müssen.

Ja, diese erstellt HTML erstellen, die streng ungültig ist. Es ist jedoch eine gültige Technik, und alle modernen Browser unterstützen es.

Wenn es mein wäre, würde ich wahrscheinlich mit meinem ersten Vorschlag gehen und sicherstellen, dass die Werte HTML-codiert sind und haben single-quotes entkommen.

+0

persönlich Ich denke, dass Technik eine schlechte Möglichkeit ist, Daten mit Knoten zu verknüpfen. http://noteslog.com/metaobjects/ ist eine leicht fortgeschrittene Technik, die jedoch eine gültige Seite enthält und zu denselben Daten führt. –

+0

Ich stimme völlig zu, dass es ein bisschen eine schmutzige Lösung ist, aber es kann sicherlich einige knifflige Dinge erheblich erleichtern. Es ist definitiv ein Nischen-Fix, obwohl;) Die "Metaobjekt" -Technik ist eine interessante, obwohl ein bisschen in sich hacky, kann ich sehen, wie es sinnvoll wäre. – Dan

0

Sind die Antworten hier, dass Sie keine Anführungszeichen verwenden JavaScript entweichen können und dass Sie müssen mit entkam Strings starten.

Daher. Es gibt keine Möglichkeit, dass JavaScript in der Lage ist, die Zeichenfolge 'Marge sagte' zu bearbeiten. Ich würde aussehen, als wäre sie 'zu Peter' und Sie müssen Ihre Daten bereinigen, bevor Sie sie dem Skript anbieten.

0

Jede gute Templating-Engine, die ihren Wert hat, wird eine "Escape Quotes" -Funktion haben. Unsere (auch selbstgewählte, wo ich arbeite) hat auch eine Funktion, Zitate für Javascript zu entkommen. In beiden Fällen wird die Template-Variable nur mit _esc oder _js_esc angehängt, je nachdem, was Sie möchten. Sie sollten niemals nutzergenerierten Inhalt an einen Browser ausgeben, der nicht maskiert wurde, IMHO.

10

Verwenden Sie versteckte Spannen, jeweils eine für jeden der Parameter <%itemid%> und <%itemname%> und schreiben Sie ihre Werte in sie.

Zum Beispiel kann die Spanne für <%itemid%> würde aussehen wie <span id='itemid' style='display:none'><%itemid%></span> und in der JavaScript-Funktion SelectSurveyItem die Argumente aus diesen Spannweiten innerHTML zu holen.

+2

Dies ist wirklich die beste Antwort. Wenn Sie die Werte in setzen und sie später mit jQuery $ ('# itemid'). Val() erhalten, ist keine spezielle Behandlung erforderlich. – Sire

0

Ich konfrontiert das gleiche Problem, und ich löste es auf eine knifflige Weise. Machen Sie zuerst globale Variablen, v1, v2 und v3. Und in der Onclick, eine Anzeige zu senden, 1, 2 oder 3 und in der Funktionskontrolle für 1, 2, 3, um den v1, v2 zu setzen, und v3 wie:

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

Abhängig von der Server-Seite Sprache, können Sie eine davon verwenden:

.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')); 

Ruby on Rails

<%= escape_javascript(jsString) %> 
+0

_ Vielen Dank! _ –

+0

Für .NET scheint Ihre Antwort der einzige Weg zu sein. 'btn.OnClientClick =" return confirm ('Sind Sie sicher?') ";' ist gültig, aber die einzige Möglichkeit, ein einzelnes Zitat einzugeben (zB '" return confirm ('Bist du sicher, oder?') ; "ist es zu kodieren ... weder Backslash noch' '' funktionieren. –

1

ich auch dieses Problem konfrontiert. Ich habe ein Skript erstellt, das einfache Anführungszeichen in doppelte Anführungszeichen umwandelt, die den HTML-Code nicht unterbrechen.

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