Escape quote ใน JavaScript


211

ฉันกำลังส่งออกค่าจากฐานข้อมูล (ไม่เปิดให้เข้าสู่สาธารณะจริงๆ แต่เปิดให้ผู้ใช้ที่ บริษัท เข้าสู่รายการ - หมายถึงฉันไม่กังวลเกี่ยวกับXSS )

ฉันพยายามที่จะออกแท็กเช่นนี้:

<a href="" onclick="DoEdit('DESCRIPTION');">Click Me</a>

DESCRIPTION เป็นค่าจากฐานข้อมูลที่มีลักษณะดังนี้:

Prelim Assess "Mini" Report

ฉันได้ลองแทนที่ "ด้วย \" แต่ไม่ว่าฉันจะลองอะไร Firefox จะตัดการโทร JavaScript ของฉันหลังจากเว้นวรรคหลังคำประเมินและมันทำให้เกิดปัญหาทุกประเภท

ฉันต้องไม่ละคำตอบที่ชัดเจน แต่สำหรับชีวิตของฉันฉันไม่สามารถหาคำตอบได้

ใครสนใจชี้ให้เห็นความโง่ของฉัน?

นี่คือหน้า HTML ทั้งหมด (มันจะเป็นหน้าASP.NETในที่สุด แต่เพื่อที่จะแก้ปัญหานี้ฉันก็เอาทุกอย่างออกไปยกเว้นรหัสปัญหา)

<html>
    <body>
        <a href="#" onclick="DoEdit('Preliminary Assessment \"Mini\"'); return false;">edit</a>
    </body>
</html>

3
เป็นความคิดที่ดีที่จะทำให้การonclickแนบกิจกรรมของคุณไม่เป็นการรบกวนและเพื่อย้ายข้อมูลฐานข้อมูลทั้งหมดของคุณไปยังเกาะข้อมูล ทุกอย่างจะสะอาดขึ้นและคุณจะได้รับข้อผิดพลาดทางไวยากรณ์บางประการเมื่อสตริงของคุณผิดพลาด
Justin Johnson


นอกจากนี้คุณยังสามารถใช้วิธีการ jquery ของ Escape ("string") และ unescape ("string") ได้
Abhiram

คำตอบ:


212

คุณต้องหลีกเลี่ยงสตริงที่คุณกำลังเขียนลงDoEditไปเพื่อกำจัดอักขระที่มีเครื่องหมายคำพูดคู่ สิ่งเหล่านี้ทำให้onclickแอตทริบิวต์ HTML ปิดก่อนกำหนด

การใช้ JavaScript escape character \นั้นไม่เพียงพอในบริบท HTML คุณจำเป็นต้องเปลี่ยนคู่อ้างกับตัวแทนนิติบุคคล XML &quot;ที่เหมาะสม


ใช่ แต่จะไม่เป็นอย่างนั้นเหรอ? <a นี่ต้องเป็น WTF ง่าย ๆ แต่สำหรับชีวิตของฉันฉันมองไม่เห็น
Matt Dawdy

มีฟังก์ชั่นจาวาสคริปต์ใด ๆ ในตัวที่จะหลีกเลี่ยงอัญประกาศ นอกเหนือจาก 'quo "' แทนที่ ('"', '& quot;') ฉันไม่พบอะไรเลย
วิน

4
มันไม่ใช่ปัญหาของจาวาสคริปต์ แต่เป็นปัญหาการเข้ารหัส HTML / XML: คุณไม่สามารถมีอักขระเครื่องหมายคำพูดคู่ภายในค่าคุณลักษณะที่ไม่มีการหลบหนี ... มิฉะนั้นเบราว์เซอร์ / ตัวแยกวิเคราะห์คิดว่าคุณกำลังสิ้นสุดการประกาศค่าแอตทริบิวต์
แอรอน

22
ตัวอย่างรหัสการแทนที่:'mystring'.replace(/"/g, '&quot;');
Joshua Burns

3
ในความคิดเห็นก่อนหน้ามีการเสนอราคาพิเศษ รหัสที่ใช้งานได้คือ 'mystring'.replace (/' / g, '& quot;');
Agustin Lopez

95

&quot; จะทำงานในกรณีนี้ตามที่แนะนำไว้ก่อนหน้าฉันเนื่องจากบริบท HTML

อย่างไรก็ตามหากคุณต้องการให้โค้ด JavaScript ของคุณถูกหลบหนีอย่างอิสระสำหรับบริบทใด ๆ คุณสามารถเลือกใช้การเข้ารหัส JavaScript ดั้งเดิม:
'กลาย\x27
"เป็น\x22

ดังนั้น onclick ของคุณจะกลายเป็น:
DoEdit('Preliminary Assessment \x22Mini\x22');

สิ่งนี้จะทำงานได้เช่นกันเมื่อผ่านสตริง JavaScript เป็นพารามิเตอร์ไปยังวิธี JavaScript อื่น ( alert()เป็นวิธีทดสอบอย่างง่ายสำหรับเรื่องนี้)

ฉันกำลังอ้างอิงถึงคำถาม Stack Overflow ที่ซ้ำกันฉันจะหลีกเลี่ยงสตริงภายในโค้ด JavaScript ภายในตัวจัดการ onClick ได้อย่างไร .


2
ขอบคุณ! คุณเป็นคำตอบที่ถูกต้องมากขึ้นเพราะมันเป็นจาวาสคริปต์พื้นเมืองโดยไม่คำนึงถึงบริบท
Scarver2

2
นี่เป็นคำตอบที่ถูกต้องแม้ว่าในบริบทของ HTML &quot;จะใช้งานได้แน่นอน
Oliver

โปรดทราบว่า&quot;จำเป็นต้องมีในค่าอินพุตเช่น<input value="\x22quoted string\x22">จะไม่ทำงาน
thdoan

@ 10basetom โดยปกติการใช้ JavaScript จะทำงานได้ในบริบท JavaScript เช่นตัวจัดการเหตุการณ์ ( onclick="...") ค่าของvalueแอตทริบิวต์ไม่ได้รับการประมวลผลภายในบริบท JavaScript เฉพาะภายในบริบท HTML
tsemer

รหัสทดแทน:'mystring'.replace(/"/g, '\\x22').replace(/'/g, '\\x27')
ไก่

33
<html>
    <body>
        <a href="#" onclick="DoEdit('Preliminary Assessment &quot;Mini&quot;'); return false;">edit</a>
    </body>
</html>

ควรทำเคล็ดลับ


24

Folks มีunescapeฟังก์ชั่นใน JavaScript อยู่แล้วซึ่งไม่ทำการหลบหนีสำหรับ\":

<script type="text/javascript">
    var str="this is \"good\"";
    document.write(unescape(str))
</script>

2
การรวมกันของ "หลบหนี" / "unescape" ทำในสิ่งที่ฉันต้องการ ขอบคุณ
ลูอิสอาร์.

8
escape / unescape เลิกใช้แล้ว แม้ว่า encodeURI ทำมากกว่าเพียงแค่คำพูด gotochriswest.com/blog/2011/05/23/escape-unescape-deprecated
chug2k

12

ปัญหาคือ HTML ไม่รู้จักอักขระเลี่ยง คุณสามารถแก้ไขได้โดยใช้เครื่องหมายคำพูดเดี่ยวสำหรับแอตทริบิวต์ HTML และเครื่องหมายคำพูดคู่สำหรับ onclick

<a href="#" onclick='DoEdit("Preliminary Assessment \"Mini\""); return false;'>edit</a>

5
Yikes ฉันสงสัยว่าทำไมฉันถึงใช้ 'สำหรับคุณสมบัติในอดีตโดยธรรมชาติ ฉันไม่เคยเจาะลึกทุกอย่างที่ลึกซึ้ง ขอบคุณ
Matt Dawdy

6

str.replace(/[\""]/g, '\\"')นี่คือวิธีที่ผมทำมันโดยทั่วไป

var display = document.getElementById('output');
var str = 'class="whatever-foo__input" id="node-key"';
display.innerHTML = str.replace(/[\""]/g, '\\"');

//will return class=\"whatever-foo__input\" id=\"node-key\"
<span id="output"></span>


2

หากคุณกำลังรวบรวม HTML ใน Java คุณสามารถใช้คลาสยูทิลิตี้ที่ดีนี้จาก Apache Commons-lang เพื่อหลบหนีอย่างถูกต้อง:

org.apache.commons.lang.StringEscapeUtils
Escapes และ unescapes Strings สำหรับ Java, Java Script, HTML, XML และ SQL


ฉันใช้ org.apache.commons.lang3.StringEscapeUtils.escapeEcmaScript (ข้อความ) เพื่อสร้าง method expression ใน Java ขอบคุณ
Harun

1

ฉันทำตัวอย่างโดยใช้ jQuery

var descr = 'test"inside"outside';
$(function(){
   $("#div1").append('<a href="#" onclick="DoEdit(descr);">Click Me</a>');       
});

function DoEdit(desc)
{
    alert ( desc );
}

และสิ่งนี้ใช้ได้ใน Internet Explorer และ Firefox


5
แน่นอนเพราะคุณไม่ได้วางไว้ในแอตทริบิวต์โดยตรง ในการใช้วิธีการของคุณฉันต้องสร้างอาร์เรย์ของสตริง JS จากนั้นทำการกำหนดจำนวน $ ("# divxxx") ... โดยมอบหมาย น้อยกว่าที่ดีที่สุด แต่ขอบคุณสำหรับคำแนะนำ
Matt Dawdy

1

คุณสามารถคัดลอกทั้งสองฟังก์ชั่น (รายการด้านล่าง) และใช้เพื่อหลีกเลี่ยง / ยกเลิกการใส่เครื่องหมายคำพูดและอักขระพิเศษทั้งหมด คุณไม่จำเป็นต้องใช้ jQuery หรือไลบรารี่อื่นสำหรับสิ่งนี้

function escape(s) {
    return ('' + s)
        .replace(/\\/g, '\\\\')
        .replace(/\t/g, '\\t')
        .replace(/\n/g, '\\n')
        .replace(/\u00A0/g, '\\u00A0')
        .replace(/&/g, '\\x26')
        .replace(/'/g, '\\x27')
        .replace(/"/g, '\\x22')
        .replace(/</g, '\\x3C')
        .replace(/>/g, '\\x3E');
}

function unescape(s) {
    s = ('' + s)
       .replace(/\\x3E/g, '>')
       .replace(/\\x3C/g, '<')
       .replace(/\\x22/g, '"')
       .replace(/\\x27/g, "'")
       .replace(/\\x26/g, '&')
       .replace(/\\u00A0/g, '\u00A0')
       .replace(/\\n/g, '\n')
       .replace(/\\t/g, '\t');

    return s.replace(/\\\\/g, '\\');
}

1

กรุณาค้นหาในรหัสด้านล่างซึ่งหนีราคาเดียวเป็นส่วนหนึ่งของสตริงที่ป้อนโดยใช้การแสดงออกปกติ มันจะตรวจสอบว่าสตริงที่ผู้ใช้ป้อนถูกคั่นด้วยเครื่องหมายจุลภาคและในเวลาเดียวกันมันก็ยังหนีคำพูดใด ๆ ที่ป้อนเป็นส่วนหนึ่งของสตริง

เพื่อที่จะหลบหนีคำพูดเพียงแค่ใส่เครื่องหมายทับย้อนกลับตามด้วยคำพูดเดียวเช่น: \ 'เป็นส่วนหนึ่งของสตริง ฉันใช้ jQuery validator สำหรับตัวอย่างนี้และคุณสามารถใช้ตามความสะดวกของคุณ

ตัวอย่างสตริงที่ถูกต้อง:

'สวัสดี'

'สวัสดีชาวโลก'

'สวัสดีชาวโลก'

'สวัสดีชาวโลก',' '

'มันเป็นโลกของฉัน', 'ไม่สามารถสนุกได้หากไม่มีฉัน', 'ยินดีต้อนรับแขก'

HTML:

<tr>
    <td>
        <label class="control-label">
            String Field:
        </label>
        <div class="inner-addon right-addon">
            <input type="text" id="stringField"
                   name="stringField"
                   class="form-control"
                   autocomplete="off"
                   data-rule-required="true"
                   data-msg-required="Cannot be blank."
                   data-rule-commaSeparatedText="true"
                   data-msg-commaSeparatedText="Invalid comma separated value(s).">
        </div>
    </td>

JavaScript:

     /**
 *
 * @param {type} param1
 * @param {type} param2
 * @param {type} param3
 */
jQuery.validator.addMethod('commaSeparatedText', function(value, element) {

    if (value.length === 0) {
        return true;
    }
    var expression = new RegExp("^((')([^\'\\\\]*(?:\\\\.[^\'\\\\])*)[\\w\\s,\\.\\-_\\[\\]\\)\\(]+([^\'\\\\]*(?:\\\\.[^\'\\\\])*)('))(((,)|(,\\s))(')([^\'\\\\]*(?:\\\\.[^\'\\\\])*)[\\w\\s,\\.\\-_\\[\\]\\)\\(]+([^\'\\\\]*(?:\\\\.[^\'\\\\])*)('))*$");
    return expression.test(value);
}, 'Invalid comma separated string values.');

0

หลบหนีจากช่องว่างเช่นกัน ฟังดูเหมือนว่า Firefox จะถือว่ามีข้อโต้แย้งสามข้อแทนที่จะเป็นข้อโต้แย้งเดียว &nbsp;เป็นอักขระช่องว่างที่ไม่ทำลาย แม้ว่าจะไม่ใช่ปัญหาทั้งหมด แต่ก็อาจเป็นความคิดที่ดี


0

คุณต้องหลีกเลี่ยงเครื่องหมายคำพูดด้วยแบ็กสแลชคู่

สิ่งนี้ล้มเหลว (ผลิตโดยjson_encodeของ PHP ):

<script>
  var jsonString = '[{"key":"my \"value\" "}]';
  var parsedJson = JSON.parse(jsonString);
</script>

งานนี้:

<script>
  var jsonString = '[{"key":"my \\"value\\" "}]';
  var parsedJson = JSON.parse(jsonString);
</script>

0

คุณสามารถใช้เมธอด escape () และ unescape () jQuery ชอบด้านล่าง

ใช้ในการหลบหนีสตริงและกู้คืนอีกครั้งโดยใช้escape(str);unescape(str_esc);

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.