如何安全地将 JS 字符串变量包裹在双引号字符中?

发布于 2024-08-24 17:08:13 字数 480 浏览 9 评论 0原文

显然,当您自己创建实际的字符串文字时,您自己会使用反斜杠转义双引号字符。

var foo = "baz\"bat";

就像您处理少数其他控制字符一样,例如换行符和反斜杠。

var bar = "baz\\bat\nmynew line and a \"quote\" ";

但是,如果您只是将现有变量包装在引号字符中,即将其提供给需要引号输入的其他系统,则会出现一些混乱。

显然,您必须转义字符串中任何潜在的双引号字符。

var doubleQuoteRe = /\"/g;
var quoted = "\"" + unquoted.replace(escaper, '\\\"') + "\"";

但根据一些人的说法,您现在还必须担心变量中转义文字反斜杠字符。换句话说,使用比我的小正则表达式更大的锤子。但是我不明白为什么。

Obviously when you're creating an actual string literal yourself, you backslash escape the double quote characters yourself.

var foo = "baz\"bat";

Just as you would with the handful of other control characters, like linebreaks and backslashes.

var bar = "baz\\bat\nmynew line and a \"quote\" ";

but if you're just wrapping that existing variable in quote character, ie to give it to some other system that requires quoted input, there's some confusion.

Obviously you have to escape any potential double quote characters that are in the string.

var doubleQuoteRe = /\"/g;
var quoted = "\"" + unquoted.replace(escaper, '\\\"') + "\"";

But according to some you also now have to worry about escaping literal backslash characters in the variable. In other words using much bigger hammer than my little regex. However i dont see why.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一刻暧昧 2024-08-31 17:08:13

您可能想避免转义已经转义的引号 -

String.prototype.inquotes=function(){
 return '"'+this.replace(/(^|[^\\])"/g,'$1\\"')+'"';
}

You might want to avoid escaping quotes you already escaped-

String.prototype.inquotes=function(){
 return '"'+this.replace(/(^|[^\\])"/g,'$1\\"')+'"';
}
单挑你×的.吻 2024-08-31 17:08:13

答案是,是的,您必须做两件事:

  1. 用两个反斜杠替换字符串中的文字反斜杠字符,
  2. 然后,继续将任何出现的“替换为\”。

为什么步骤 1 至关重要的最简单解释是考虑 5 个字符的字符串:

foo\"   

在前 3 个字符 (foo) 之后,字符串中有一个文字反斜杠字符,然后是一个文字双引号字符。

(换句话说,作为字符串文字,这看起来像“foo\”“)

如果我只替换引号字符,我最终会得到一个带引号的字符串,其值为

foo\\"     

但是这里的两个反斜杠将被解释为 最终会得到不平衡的引号。

"foo\\""

因此,当我将此值括在引号中时,如果我先执行步骤 1(将所有反斜杠替换为双反斜杠),

foo\\"

然后执行步骤 2(将引号替换为),则 斜杠引号

foo\\\"

现在当我用引号字符包裹我的值时,我终于得到了

"foo\\\""

正确的结果。

The answer is that yes, you have to do two things:

  1. replace literal backslash characters in the string, with two backslashes,
  2. THEN, you proceed replacing any occurrences of " with \".

the simplest explanation for why step 1 is essential, is to consider the 5-character string :

foo\"   

After the first 3 characters (foo), there is a literal backslash character in the string, and then there is a literal double quote character.

(Put another way, as a string literal this would look like "foo\"")

If I were to only replace the quote character, i'd end up with a quoted string whose value was

foo\\"     

But the two backslashes here will be interpreted as a single backslash. So when I wrap this value in quotes, I end up with unbalanced quotes.

"foo\\""

on the other hand, if I do step 1 first -- replacing all backslashes with double backslashes gives

foo\\"

and then step 2 -- replacing the quote with slash-quote gives

foo\\\"

Now when i wrap my value in quote characters i finally get

"foo\\\""

which is correct.

地狱即天堂 2024-08-31 17:08:13

FF 中有一个非标准的 str.quote()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/quote
他们建议使用以下polyfill

    if(!String.prototype.quote){
  // oop version - no dependencies
  String.prototype.quote = (function(){
    // prepare fallback
    // ----------------
    // backslash escape double quotes and backslashes
    var escp_regex = /[\\"]/g,
      escp_callback = '\\
amp;',
      // escape control characters
      ctrl_map = {
        '\b': '\\b', // backspace
        '\t': '\\t', // tab
        '\n': '\\n', // new line
        '\f': '\\f', // form feed
        '\r': '\\r'  // carriage return
      },
      // don't rely on `Object.keys(ctrl_map).join('')`
      ctrl_regex = new RegExp('[\b\t\n\f\r]', 'g'),
      ctrl_callback = function(match){
        return ctrl_map[match];
      },
      // hex-escape, spare out control characters and ASCII printables
      // [0-7,11,14-31,127-255]
      xhex_regex = /[\x00-\x07\x0B\x0E-\x1F\x7F-\xFF]/g,
      xhex_callback = function(match, char_code){
        char_code = match.charCodeAt(0);
        return '\\x' + (char_code < 16 ? '0' : '') + char_code;
      },
      // hex-escape all others
      uhex_regex = /[\u0100-\uFFFF]/g,
      uhex_callback = function(match, char_code){
        char_code = match.charCodeAt(0);
        return '\\u' + (char_code < 4096 ? '0' : '') + char_code;
      },
      // delegate to native `JSON.stringify` if available
      stringify = typeof JSON !== 'undefined' && JSON.stringify;

    // return actual polyfill
    // ----------------------
    return function(){
      var self = this; // promote compression
      if(self == null) throw new TypeError('can\'t convert ' + self + ' to object');
      if(stringify) return stringify(self);
      return '"' + self
        .replace(escp_regex, escp_callback)
        .replace(ctrl_regex, ctrl_callback)
        .replace(xhex_regex, xhex_callback)
        .replace(uhex_regex, uhex_callback) + '"';
    }
  }());

  // generic version - requires Function#bind
  String.quote = Function.call.bind(''.quote);
}

There is a non standard str.quote() in FF

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/quote
They suggest the following polyfill

    if(!String.prototype.quote){
  // oop version - no dependencies
  String.prototype.quote = (function(){
    // prepare fallback
    // ----------------
    // backslash escape double quotes and backslashes
    var escp_regex = /[\\"]/g,
      escp_callback = '\\
amp;',
      // escape control characters
      ctrl_map = {
        '\b': '\\b', // backspace
        '\t': '\\t', // tab
        '\n': '\\n', // new line
        '\f': '\\f', // form feed
        '\r': '\\r'  // carriage return
      },
      // don't rely on `Object.keys(ctrl_map).join('')`
      ctrl_regex = new RegExp('[\b\t\n\f\r]', 'g'),
      ctrl_callback = function(match){
        return ctrl_map[match];
      },
      // hex-escape, spare out control characters and ASCII printables
      // [0-7,11,14-31,127-255]
      xhex_regex = /[\x00-\x07\x0B\x0E-\x1F\x7F-\xFF]/g,
      xhex_callback = function(match, char_code){
        char_code = match.charCodeAt(0);
        return '\\x' + (char_code < 16 ? '0' : '') + char_code;
      },
      // hex-escape all others
      uhex_regex = /[\u0100-\uFFFF]/g,
      uhex_callback = function(match, char_code){
        char_code = match.charCodeAt(0);
        return '\\u' + (char_code < 4096 ? '0' : '') + char_code;
      },
      // delegate to native `JSON.stringify` if available
      stringify = typeof JSON !== 'undefined' && JSON.stringify;

    // return actual polyfill
    // ----------------------
    return function(){
      var self = this; // promote compression
      if(self == null) throw new TypeError('can\'t convert ' + self + ' to object');
      if(stringify) return stringify(self);
      return '"' + self
        .replace(escp_regex, escp_callback)
        .replace(ctrl_regex, ctrl_callback)
        .replace(xhex_regex, xhex_callback)
        .replace(uhex_regex, uhex_callback) + '"';
    }
  }());

  // generic version - requires Function#bind
  String.quote = Function.call.bind(''.quote);
}
骄傲 2024-08-31 17:08:13

您可能想要转义除引号之外的其他字符,例如空白字符(换行符!)和/或非 ASCII 字符。有 Crockford 的 quote(),可以找到我自己的实现位于 mercurial.intuxication.org

You might want to escape other characters aside from quotes, eg whitespace characters (newlines!) and/or non-ASCII characters. There's Crockford's quote(), and my own implementation can be found at mercurial.intuxication.org.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文