【问题标题】:How to escape a JSON string containing newline characters using JavaScript?如何使用 JavaScript 转义包含换行符的 JSON 字符串?
【发布时间】:2011-05-14 07:03:00
【问题描述】:

我必须形成一个 JSON 字符串,其中一个值具有换行符。这必须转义,然后使用 AJAX 调用发布。任何人都可以建议一种使用 JavaScript 转义字符串的方法。我没有使用 jQuery。

【问题讨论】:

  • 我尝试将换行符 \n 转义为 \\n。它工作正常。但我正在寻找任何可以为所有转义字符执行此操作的 JS 库。
  • 为什么需要转义 JSON 中的换行符?这些值在使用时是如何解码的,因为合适的解决方案是使用相关的编码函数。
  • 我花了 6 个小时尝试各种不同的东西,结果发现一个小小的额外斜线会让它像魔术一样工作我认为很难的事情花了 5 分钟......这件事我以为得到了成为不可能的..omg
  • 当你使用 Ajax-calls 和 Server-Side php-db-saving 时,只需使用 php-functionaddslashes() 来转换它。使用此解决方案,您只有一个地方可以转换,而且比 javascript-replace 行更干净。

标签: javascript escaping


【解决方案1】:

获取您的 JSON 并 .stringify() 它。然后使用.replace() 方法并将所有出现的\n 替换为\\n

编辑:

据我所知,没有知名的 JS 库可以转义字符串中的所有特殊字符。但是,您可以链接 .replace() 方法并替换所有特殊字符,如下所示:

var myJSONString = JSON.stringify(myJSON);
var myEscapedJSONString = myJSONString.replace(/\\n/g, "\\n")
                                      .replace(/\\'/g, "\\'")
                                      .replace(/\\"/g, '\\"')
                                      .replace(/\\&/g, "\\&")
                                      .replace(/\\r/g, "\\r")
                                      .replace(/\\t/g, "\\t")
                                      .replace(/\\b/g, "\\b")
                                      .replace(/\\f/g, "\\f");
// myEscapedJSONString is now ready to be POST'ed to the server. 

但这很糟糕,不是吗?输入函数的美妙之处在于,它们允许您将代码分解为多个片段并保持脚本的主要流程干净,并且没有 8 个链接的 .replace() 调用。因此,让我们将该功能放入一个名为escapeSpecialChars() 的函数中。让我们继续把它附加到String对象的prototype chain,这样我们就可以直接在String对象上调用escapeSpecialChars()

像这样:

String.prototype.escapeSpecialChars = function() {
    return this.replace(/\\n/g, "\\n")
               .replace(/\\'/g, "\\'")
               .replace(/\\"/g, '\\"')
               .replace(/\\&/g, "\\&")
               .replace(/\\r/g, "\\r")
               .replace(/\\t/g, "\\t")
               .replace(/\\b/g, "\\b")
               .replace(/\\f/g, "\\f");
};

一旦我们定义了那个函数,我们的代码主体就这么简单:

var myJSONString = JSON.stringify(myJSON);
var myEscapedJSONString = myJSONString.escapeSpecialChars();
// myEscapedJSONString is now ready to be POST'ed to the server

【讨论】:

  • 谢谢亚历克斯。我必须为所有转义字符执行此操作,对吗?有没有 JS 库可以做到这一点?
  • 这是解决我的问题的确切函数 String.prototype.escapeSpecialChars = function() { return this.replace(/\\/g, "\\\\").替换(/\n/g,“\\n”)。替换(/\r/g,“\\r”)。替换(/\t/g,“\\t”)。替换(/\f/g,“\\f”)。替换(/"/g,"\\\"")。替换(/'/g,"\\\'")。替换(/\&/g, "\\&"); }
  • 正如 user667073 的回答中所述,此解决方案存在一些错误。请参阅 json.org - & 和 ' 不得 转义。
  • 我不得不对此投反对票,因为正则表达式似乎是错误的。我尝试使用它,但必须通过删除其中一个斜杠来修复正则表达式,例如:/\\n/g 应该是 /\n/g。有关详细信息,请参阅此链接中的“不可打印字符” - RegExp Info
  • 为了避免反斜杠,添加.replace(/\\/g, "\\\\")。有点遗憾,我们不得不这样做,并且没有js提供的功能。
【解决方案2】:

根据 user667073 的建议,除了首先重新排序反斜杠替换,并修复引号替换

escape = function (str) {
  return str
    .replace(/[\\]/g, '\\\\')
    .replace(/[\"]/g, '\\\"')
    .replace(/[\/]/g, '\\/')
    .replace(/[\b]/g, '\\b')
    .replace(/[\f]/g, '\\f')
    .replace(/[\n]/g, '\\n')
    .replace(/[\r]/g, '\\r')
    .replace(/[\t]/g, '\\t');
};

【讨论】:

  • 你不必做所有这些。只有反斜杠、换行符、换行符和两个引号。它不见了:单引号,Line separator \u2028Paragraph separator \u2029。参考:es5.github.io/#x7.3
  • 很好,但为什么需要方括号而不是:escape = function (str) { return str .replace(/\\/g, '\\\\') .replace(/\ "/g, '\\\"') .replace(/\//g, '\\/') .replace(/\b/g, '\\b') .replace(/\f/g, '\\f') .replace(/\n/g, '\\n') .replace(/\r/g, '\\r') .replace(/\t/g, '\\t' ); };
  • 完美。接受的答案(在这个答案之上)根本不起作用。使用 nodeJS。
  • 我收到此错误:Uncaught SyntaxError: Unexpected token \ in JSON at position 2
【解决方案3】:

和你一样,我一直在研究几个 cmets 并发布以替换我的 JSON 中的特殊转义字符,其中包含 html 对象。

我的目标是删除 JSON 对象中的特殊字符,并渲染 json 对象中的 html。

这是我所做的,希望它非常易于使用。

首先我做了 JSON.stringify 我的 json 对象和 JSON.parse 结果。

例如:

JSON.parse(JSON.stringify(jsonObject));

它解决了我的问题并使用纯 Javascript 完成。

【讨论】:

  • 这绝对是要走的路
  • 这绝对是要走的路!
  • 这肯定会在复杂和大型对象上出现stackoverflow 错误
  • 在包含正文和一些表格的 html 文件中尝试 JSON.parse(JSON.stringify($("body")))。 $("body") 是一个 javascript 对象,但 stringify 将无法解析它。
  • 我会检查您的查询并回复。
【解决方案4】:

我不敢说亚历克斯给出的答案是相当不正确的,委婉地说:

  • Alex 尝试转义的某些字符根本不需要转义(例如 & 和 ');
  • \b 根本不是退格字符,而是单词边界匹配
  • 不处理需要转义的字符。

这个功能

escape = function (str) {
    // TODO: escape %x75 4HEXDIG ?? chars
    return str
      .replace(/[\"]/g, '\\"')
      .replace(/[\\]/g, '\\\\')
      .replace(/[\/]/g, '\\/')
      .replace(/[\b]/g, '\\b')
      .replace(/[\f]/g, '\\f')
      .replace(/[\n]/g, '\\n')
      .replace(/[\r]/g, '\\r')
      .replace(/[\t]/g, '\\t')
    ; };

似乎是一个更好的近似值。

【讨论】:

  • 实际上你应该改变顺序来替换双引号之前的反斜杠,否则你会得到 \\\\"。另外引号应该是 .replace(/[\" ]/g, '\\\"')
【解决方案5】:

单引号的小更新

function escape (key, val) {
    if (typeof(val)!="string") return val;
    return val      
        .replace(/[\\]/g, '\\\\')
        .replace(/[\/]/g, '\\/')
        .replace(/[\b]/g, '\\b')
        .replace(/[\f]/g, '\\f')
        .replace(/[\n]/g, '\\n')
        .replace(/[\r]/g, '\\r')
        .replace(/[\t]/g, '\\t')
        .replace(/[\"]/g, '\\"')
        .replace(/\\'/g, "\\'"); 
}

var myJSONString = JSON.stringify(myJSON,escape);

【讨论】:

    【解决方案6】:

    这是一个旧帖子。但它可能对那些使用 angular.fromJson 和 JSON.stringify 的人仍然有用。 escape() 已弃用。 改用这个,

    var uri_enc = encodeURIComponent(uri); //before you post the contents
    var uri_dec = decodeURIComponent(uri_enc); //before you display/use the contents.
    

    参考http://www.w3schools.com/jsref/jsref_decodeuricomponent.asp

    【讨论】:

    • stringify 已经为你完成了所有的转义——我很好奇为什么不直接使用它呢? git.io/vglq7
    【解决方案7】:

    JSON.stringify 上还有第二个参数。因此,更优雅的解决方案是:

    function escape (key, val) {
        if (typeof(val)!="string") return val;
        return val
          .replace(/[\"]/g, '\\"')
          .replace(/[\\]/g, '\\\\')
          .replace(/[\/]/g, '\\/')
          .replace(/[\b]/g, '\\b')
          .replace(/[\f]/g, '\\f')
          .replace(/[\n]/g, '\\n')
          .replace(/[\r]/g, '\\r')
          .replace(/[\t]/g, '\\t')
        ; 
    }
    
    var myJSONString = JSON.stringify(myJSON,escape);
    

    【讨论】:

      【解决方案8】:

      这是一个老问题,但解决方案对我来说效果不佳,因为它没有解决所有情况。我终于找到了一个可以完成工作的答案here

      我将发布我使用转义和编码 uri 组件的组合解决方案:

      // implement JSON stringify serialization
      JSON.stringify = JSON.stringify || function (obj) {
          var t = typeof (obj);
          if (t != "object" || obj === null) {
              // simple data type
              if (t == "string") obj = '"'+obj+'"';
              return String(obj);
          }
          else {
              // recurse array or object
              var n, v, json = [], arr = (obj && obj.constructor == Array);
              for (n in obj) {
                  v = obj[n]; t = typeof(v);
                  if (t == "string") v = '"'+v+'"';
                  else if (t == "object" && v !== null) v = JSON.stringify(v);
                  json.push((arr ? "" : '"' + n + '":') + String(v));
              }
              var rawString = (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
             return rawString;
          }
      };
      function escape (key, val) {
          if (typeof(val)!="string") return val;
      
          var replaced = encodeURIComponent(val);
          return replaced;
      }
      
      JSON.stringifyEscaped = function(obj){
          return JSON.stringify(obj,escape);
      }
      

      【讨论】:

      • 也许之后也删除字符串周围的双引号? escape = (string) -> JSON.stringify(string)[1...-1]
      【解决方案9】:

      最好使用JSON.parse(yourUnescapedJson);

      【讨论】:

        【解决方案10】:

        如果您的服务器端脚本语言是 PHP,请使用 json_encode()json_encode() 为您转义换行符和其他意外标记 (如果不使用 PHP,请为您的脚本语言寻找类似的功能)

        然后在你的 JavaScript 中使用$.parseJSON(),完成!

        【讨论】:

        • 如果将数据从 php 传递到 javascript 作为 JSON 字符串,请检查这个答案 - 双重转义,帮助我传递 JSON.parse 并将 json 字符串转换为对象。 <script> windows.data_from_php = <?php echo json_encode(json_encode($arrayOrObjToJs)); ?>; var phpData = JSON.parse(windows.data_from_php); </script>php JSON.parse double encode
        【解决方案11】:

        编辑:检查您正在与之交互的 api 是否设置为Content-Type: application/json,&/或您的客户端 http 库是否在后台进行字符串化和解析 http 请求正文。我的客户端库是由 swagger 生成的,这也是我需要应用这些 hack 的原因,因为客户端库正在对我的 pre 字符串化主体(body: “jsonString”,而不是 body: { ...normal payload })进行字符串化。我所要做的就是将 api 更改为 Content-Type: text/plain,它删除了该路由上的 JSON 字符串化/解析,然后就不需要这些黑客了。您也可以只更改 api 的“使用”或“生产”部分,see here

        原文:如果您的 Google 不断将您登陆到这里并且您的 api 抛出错误,除非您的 JSON 双引号被转义 ("{\"foo\": true}"),那么您需要做的就是字符串化两次,例如JSON.stringify(JSON.stringify(bar))

        【讨论】:

        • 谢谢@jasonco,但不是真的。这个问题有十年了!检查我的编辑,它可能会对你有所帮助。
        • 嗨@Andrew,谢谢!你的原始答案仍然对我有帮助,至少对于我正在做的事情,这也有点 hacky :)
        【解决方案12】:

        我在一次 Ajax 调用中遇到了同样的情况,其中 JSON 由于 Textarea 字段中的换行符而引发错误。这里给出的解决方案对我不起作用。 所以我使用了 Javascript 的 .escape 函数,它运行良好。然后为了从JSON 中检索值,我只是使用.unescape 进行了转义。

        【讨论】:

        • 使用 Ajax 调用,我更喜欢使用 php-function newStr = addlashes(str),然后保存到 db。所以我不必在 javascript(客户端)端进行转换。使用此解决方案,您只需要一个地方来转换斜线。我对这个解决方案非常满意。
        【解决方案13】:

        我使用内置的jQuery.serialize() 从文本区域中提取值以对输入进行urlencode。优点是您不必自己搜索替换每个特殊字符,而且我还保留换行符和转义 html。为了使序列化工作,输入字段似乎需要具有名称属性,并且它还向需要替换的转义字符串添加了相同的属性。可能不是您想要的,但它对我有用。

        var myinputfield = jQuery("#myinputfield"); 
        var text = myinputfield.serialize();
        text = text.replace(myinputfield.attr('name') + '=','');
        

        【讨论】:

          【解决方案14】:

          在使用任何形式的 Ajax 时,Web 上似乎都缺乏关于从 CGI 服务器接收到的响应格式的详细文档。此处的一些条目指出,必须转义返回的文本或 json 数据中的换行符,以防止 JSON 转换(可能通过抛出未捕获的异常创建)中的无限循环(挂起),无论是由 jQuery 自动完成还是使用 Javascript 系统或库 JSON 解析手动完成来电。

          在程序员发布此问题的每种情况下,都会提出不充分的解决方案(通常在发送方将 \n 替换为 \\n)并且该问题被放弃。当传递意外嵌入控制转义序列的字符串值(例如 Windows 路径名)时,就会发现它们的不足之处。一个例子是 "C:\Chris\Roberts.php",它包含控制字符 ^c 和 ^r,这会导致字符串 {"file":"C:\Chris\Roberts.php"} 的 JSON 转换为永远循环。生成此类值的一种方法是故意尝试将 PHP 警告和错误消息从服务器传递到客户端,这是一个合理的想法。

          根据定义,Ajax 在后台使用 HTTP 连接。此类连接使用 GET 和 POST 传递数据,这两种方法都需要对发送的数据进行编码以避免语法错误,包括控制字符。

          这为构建看似解决方案提供了足够的提示(它需要更多测试):在 PHP(发送)端使用 rawurlencode 对数据进行编码,并在 Javascript(接收)端使用 unescape 进行解码数据。在某些情况下,您会将它们应用于整个文本字符串,在其他情况下,您将仅将它们应用于 JSON 中的值。

          如果这个想法被证明是正确的,可以构建简单的例子来帮助各级程序员一劳永逸地解决这个问题。

          【讨论】:

            【解决方案15】:

            RegExp 单行,使用这个函数:

            function escapeJSON(string) {
                return string.replace(/[\n"\&\r\t\b\f]/g, '\\$&');
            }
            

            【讨论】:

              【解决方案16】:

              看起来这确实是一篇古老的帖子 :-) 但是,伙计们,我对此的最佳解决方法是 100% 无需复杂代码即可工作,即同时使用编码/解码到 base64 的两种功能。它们是 atob() 和 btoa()。迄今为止最简单、最好的方法,如果您错过任何要转义的字符,无需担心。

              乔治

              【讨论】:

              • 因为我想出了相同的解决方案。我想知道是否有人可以澄清这个解决方案以及是否有一些隐藏的警告。谢谢。
              • @mahish 参加聚会有点晚了,但是您必须担心 'Latin1' 范围之外的字符,例如 ✓ à la 模式您可以 encodeURIComponent 并且不会收到 JavaScript 错误,但是您当您调用恢复数据时,将丢失编号较高的 unicode 字符。所以编码:var b = btoa(encodeURIComponent(q).replace(/%([0-9A-F]{2})/g, function (m, p1) { return String.fromCharCode('0x' + p1) })) 解码:var u = decodeURIComponent(escape(atob(b))) 大部分来自各种问题的堆栈溢出答案。
              【解决方案17】:

              使用 encodeURIComponent() 对字符串进行编码。

              例如。 var myEscapedJSONString = encodeURIComponent(JSON.stringify(myJSON));

              您不需要对其进行解码,因为网络服务器会自动执行相同的操作。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-02-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-09-19
                相关资源
                最近更新 更多