Thoát dấu ngoặc kép trong JavaScript


211

Tôi xuất ra các giá trị từ cơ sở dữ liệu (nó không thực sự mở cho mục nhập công khai, nhưng nó được mở bởi mục nhập của người dùng tại công ty - có nghĩa là, tôi không lo lắng về XSS ).

Tôi đang cố gắng xuất ra một thẻ như thế này:

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

MÔ TẢ thực sự là một giá trị từ cơ sở dữ liệu giống như thế này:

Prelim Assess "Mini" Report

Tôi đã thử thay thế "bằng \", nhưng dù tôi có cố gắng thế nào, Firefox vẫn tiếp tục cắt cuộc gọi JavaScript của tôi sau khoảng trống sau từ Đánh giá và nó gây ra đủ loại vấn đề.

Tôi phải bực bội câu trả lời rõ ràng, nhưng đối với cuộc sống của tôi, tôi không thể tìm ra nó.

Bất cứ ai quan tâm để chỉ ra sự ngốc nghếch của tôi?

Đây là toàn bộ trang HTML ( cuối cùng sẽ là một trang ASP.NET , nhưng để giải quyết vấn đề này, tôi đã lấy ra mọi thứ khác trừ mã vấn đề)

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

3
Đó là một ý tưởng tốt để làm cho onclicktệp đính kèm sự kiện của bạn không bị phô trương và để di chuyển tất cả thông tin cơ sở dữ liệu của bạn vào một đảo dữ liệu. Mọi thứ sẽ sạch hơn và bạn thực sự sẽ gặp một số lỗi cú pháp khi chuỗi của bạn bị thoát sai.
Justin Johnson


Bạn cũng có thể sử dụng các phương thức jquery
esc

Câu trả lời:


212

Bạn cần thoát khỏi chuỗi bạn đang viết ra DoEditđể xóa các ký tự trích dẫn kép. Chúng đang khiến onclickthuộc tính HTML đóng sớm.

Sử dụng ký tự thoát JavaScript \, không đủ trong ngữ cảnh HTML. Bạn cần thay thế trích dẫn kép bằng biểu diễn thực thể XML thích hợp , &quot;.


Phải, nhưng đó không phải là điều này? <a href="#" onclick="DoEdit('Preliminary Assessment \"Mini\"'); return false;"> chỉnh sửa </a> Tôi đã thử điều đó và nó vẫn đang gặp rắc rối. Đây phải là một WTF đơn giản nhưng đối với cuộc sống của tôi, tôi không thể nhìn thấy nó.
Matt Dawdy

Có bất kỳ chức năng JavaScript tích hợp nào có thể thoát khỏi dấu ngoặc kép không? Ngoài 'quo "'. Thay thế ('"', '& quot;') Tôi không thể tìm thấy bất cứ điều gì.
kevin

4
Đây không phải là vấn đề javascript, đó là vấn đề mã hóa HTML / XML: bạn không thể có các ký tự trích dẫn kép bên trong một giá trị thuộc tính mà không thoát khỏi chúng ... nếu không trình duyệt / trình phân tích cú pháp nghĩ rằng bạn đang kết thúc khai báo giá trị thuộc tính.
Aaron

22
mã thay thế ví dụ:'mystring'.replace(/"/g, '&quot;');
Joshua Burns

3
trong các bình luận trước đó có một trích dẫn thêm. Mã hoạt động là 'mystring'.replace (/' / g, '& quot;');
Agustin Lopez

95

&quot; sẽ hoạt động trong trường hợp cụ thể này, như được đề xuất trước tôi, vì bối cảnh HTML.

Tuy nhiên, nếu bạn muốn mã JavaScript của mình được thoát độc lập cho bất kỳ ngữ cảnh nào, bạn có thể chọn mã hóa JavaScript gốc:
'trở \x27
"thành\x22

Vì vậy, onclick của bạn sẽ trở thành:
DoEdit('Preliminary Assessment \x22Mini\x22');

Ví dụ, điều này cũng hoạt động khi truyền chuỗi JavaScript dưới dạng tham số cho phương thức JavaScript khác ( alert()là phương pháp kiểm tra dễ dàng cho việc này).

Tôi đang giới thiệu cho bạn câu hỏi về Stack Overflow trùng lặp, Làm cách nào để thoát một chuỗi bên trong mã JavaScript bên trong trình xử lý onClick? .


2
Cảm ơn bạn! Của bạn là câu trả lời đúng hơn bởi vì nó là JavaScript gốc bất kể bối cảnh.
Scarver2

2
Đây là câu trả lời đúng, mặc dù trong bối cảnh HTML sử dụng &quot;ý chí, tất nhiên, sẽ hoạt động.
Oliver

Lưu ý rằng &quot;được yêu cầu trong các giá trị đầu vào, nghĩa là, <input value="\x22quoted string\x22">sẽ không hoạt động.
thdoan

@ 10basetom một cách tự nhiên, JavaScript thoát chỉ hoạt động trong ngữ cảnh JavaScript, như trình xử lý sự kiện ( onclick="..."). Giá trị của một valuethuộc tính không được xử lý trong ngữ cảnh JavaScript, chỉ trong bối cảnh HTML.
tsemer

mã thay thế:'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>

Nên làm thủ thuật.


24

Thưa các bạn, đã có unescapechức năng trong JavaScript, điều này không giải thích cho \":

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

2
Một sự kết hợp của "thoát" / "unescape" đã làm những gì tôi cần. Cảm ơn.
Luis R.

8
thoát / unescape bị phản đối. mặc dù encodeURI không chỉ trích dẫn. gotochriswest.com/blog/2011/05/23/escape-unescape-deprecated
chug2k

12

Vấn đề là HTML không nhận ra ký tự thoát. Bạn có thể giải quyết vấn đề đó bằng cách sử dụng các trích dẫn đơn cho thuộc tính HTML và dấu ngoặc kép cho onclick.

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

5
Rất tiếc. Tôi đã tự hỏi tại sao tôi tự nhiên sử dụng 'cho thuộc tính trong quá khứ. Tôi chỉ không bao giờ đào sâu vào tất cả những điều đó sâu sắc. Cảm ơn.
Matt Dawdy

6

Đây là cách tôi làm nó, về cơ bản 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

Nếu bạn đang lắp ráp HTML trong Java, bạn có thể sử dụng lớp tiện ích tuyệt vời này từ Apache commons-lang để thực hiện tất cả các thoát chính xác:

org.apache.commons.lang.StringEscapeUtils
Chuỗi thoát và unescapes cho Java, Java Script, HTML, XML và SQL.


Tôi sử dụng org.apache.commons.lang3.StringEscapeUtils.escapeEcmaScript (văn bản) để xây dựng phương thứcExpression trong Java. Cảm ơn.
Harun

1

Tôi đã thực hiện một mẫu bằng cách sử dụng jQuery

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

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

Và điều này hoạt động trong Internet Explorer và Firefox.


5
Tất nhiên là có, bởi vì bạn không đặt nó trực tiếp vào thuộc tính. Để sử dụng phương thức của bạn, tôi phải tạo một chuỗi các chuỗi JS, sau đó thực hiện một số lượng tùy ý $ ("# divxxx") ... các bài tập. Ít hơn tối ưu, nhưng nhờ gợi ý.
Matt Dawdy

1

Bạn có thể sao chép hai chức năng đó (được liệt kê bên dưới) và sử dụng chúng để thoát / hủy bỏ tất cả các trích dẫn và ký tự đặc biệt. Bạn không phải sử dụng jQuery hoặc bất kỳ thư viện nào khác cho việc này.

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

Vui lòng tìm trong đoạn mã dưới đây thoát khỏi dấu ngoặc đơn như một phần của chuỗi đã nhập bằng biểu thức chính quy. Nó xác nhận nếu chuỗi do người dùng nhập được phân tách bằng dấu phẩy và đồng thời nó thậm chí thoát khỏi bất kỳ trích dẫn nào được nhập dưới dạng một phần của chuỗi.

Để thoát dấu ngoặc đơn, chỉ cần nhập dấu gạch chéo ngược theo sau là một trích dẫn duy nhất như: \ ' là một phần của chuỗi. Tôi đã sử dụng trình xác nhận jQuery cho ví dụ này và bạn có thể sử dụng theo sự thuận tiện của mình.

Ví dụ chuỗi hợp lệ:

'Xin chào'

'Chào thế giới'

'Chào thế giới'

'Chào thế giới',' '

'Đó là thế giới của tôi', 'Không thể tận hưởng điều này mà không có tôi.', 'Chào mừng, Khách'

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

Thoát khỏi khoảng trắng là tốt. Nghe có vẻ như Firefox đang giả sử ba đối số thay vì một. &nbsp;là nhân vật không gian không phá vỡ. Ngay cả khi nó không phải là toàn bộ vấn đề, nó vẫn có thể là một ý tưởng tốt.


0

Bạn cần phải thoát dấu ngoặc kép với dấu gạch chéo kép.

Điều này không thành công (được sản xuất bởi json_encode của PHP ):

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

Những công việc này:

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

0

Bạn có thể sử dụng các phương thức jQuery esc () và unescape (). Giống như bên dưới,

Sử dụng escape(str);để thoát khỏi chuỗi và phục hồi lại bằng cách sử dụng unescape(str_esc);.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.