I have to form a JSON string in which a value is having new line character. This has to be escaped and then posted using AJAX call. Can any one suggest a way to escape the string with JavaScript. I am not using jQuery.
问题:
回答1:
Take your JSON and .stringify()
it. Then use the .replace()
method and replace all occurrences of \\n
with \\\\n
.
EDIT:
As far as I know of, there are no well-known JS libraries for escaping all special characters in a string. But, you could chain the .replace()
method and replace all of the special characters like this:
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.
But that\'s pretty nasty, isn\'t it? Enter the beauty of functions, in that they allow you to break code into pieces and keep the main flow of your script clean, and free of 8 chained .replace()
calls. So let\'s put that functionality into a function called, escapeSpecialChars()
. Let\'s go ahead and attach it to the prototype chain
of the String
object, so we can call escapeSpecialChars()
directly on String objects.
Like so:
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\");
};
Once we have defined that function, the main body of our code is as simple as this:
var myJSONString = JSON.stringify(myJSON);
var myEscapedJSONString = myJSONString.escapeSpecialChars();
// myEscapedJSONString is now ready to be POST\'ed to the server
回答2:
As per user667073 suggested, except reordering the backslash replacement first, and fixing the quote replacement
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\');
};
回答3:
Like you, I have been looking into several comments and post to replace special escape characters in my JSON which contains html object inside that.
My object is to remove the special characters in JSON object and also render the html which is inside the json object.
Here is what I did and hope its very simple to use.
First I did JSON.stringify my json object and JSON.parse the result.
For eg:
JSON.parse(JSON.stringify(jsonObject));
And it solves my problem and done using Pure Javascript.
回答4:
I\'m afraid to say that answer given by Alex is rather incorrect, to put it mildly:
- Some characters Alex tries to escape are not required to be escaped at all (like & and \');
- \\b is not at all the backspace character but rather a word boundary match
- Characters required to be escaped are not handled.
This function
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\')
; };
appears to be a better approximation.
回答5:
A small update for single quotes
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:
this is an old post. but it may still be helpful for those using angular.fromJson, and JSON.stringify. escape() is deprecated. use this instead,
var uri_enc = encodeURIComponent(uri); //before you post the contents
var uri_dec = decodeURIComponent(uri_enc); //before you display/use the contents.
ref http://www.w3schools.com/jsref/jsref_decodeuricomponent.asp
回答7:
There is also second parameter on JSON.stringify. So, more elegant solution would be:
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:
This is an old question but the solution did not work well for me as it did not solve all cases. I finally found an answer that did the job here
I will post my combined solution of both using escape and encode uri component:
// 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);
}
回答9:
I got same situation in one of my Ajax calls, where JSON
was throwing an error due to the newline in the Textarea field. The solution given here didn\'t worked for me.
So i used Javascript\'s .escape
function and it worked fine. Then to retrieve the value from JSON
, I just unescaped using .unescape
.
回答10:
When using any form of Ajax, detailed documentation for the format of responses received from the CGI server seems to be lacking on the Web. Some entries here point out that newlines in returned text or json data must be escaped to prevent infinite loops (hangs) in JSON conversion (possibly created by throwing an uncaught exception), whether done automatically by jQuery or manually using Javascript system or library JSON parsing calls.
In each case where programmers post this problem, inadequate solutions are presented (most often replacing \\n by \\\\n on the sending side) and the matter is dropped. Their inadequacy is revealed when passing string values that accidentally embed control escape sequences, such as Windows pathnames. An example is \"C:\\Chris\\Roberts.php\", which contains the control characters ^c and ^r, which can cause JSON conversion of the string {\"file\":\"C:\\Chris\\Roberts.php\"} to loop forever. One way of generating such values is deliberately to attempt to pass PHP warning and error messages from server to client, a reasonable idea.
By definition, Ajax uses HTTP connections behind the scenes. Such connections pass data using GET and POST, both of which require encoding sent data to avoid incorrect syntax, including control characters.
This gives enough of a hint to construct what seems to be a solution (it needs more testing): to use rawurlencode on the PHP (sending) side to encode the data, and unescape on the Javascript (receiving) side to decode the data. In some cases, you will apply these to entire text strings, in other cases you will apply them only to values inside JSON.
If this idea turns out to be correct, simple examples can be constructed to help programmers at all levels solve this problem once and for all.
回答11:
use json_encode() if your server side scripting lang is php, json_encode() escapes the newline & other unexpected tokens for you (if not php look for similar function for your scripting lan)
then use $.parseJSON() in your javascript, done!
回答12:
I used the built in jQuery.serialize() to extract the value from a textarea to urlencode the input. The pro part is that you don\'t have to search replace every special char on your own and i also keep the newlines and escapes html. For serialize to work it seems the input field needs to have a name attribute though and it also adds same attribute to the escaped string which needs to be replaced away. Might not be what you are looking for but it works for me.
var myinputfield = jQuery(\"#myinputfield\");
var text = myinputfield.serialize();
text = text.replace(myinputfield.attr(\'name\') + \'=\',\'\');
回答13:
Looks like this is an ancient post really :-) But guys, the best workaround I have for this, to be 100% that it works without complicated code, is to use both functions of encoding/decoding to base64. These are atob() and btoa(). By far the easiest and best way, no need to worry if you missed any characters to be escaped.
George
回答14:
It\'s better to use JSON.parse(yourUnescapedJson);
回答15:
Don\'t ever use regular expressions (I mean like never at all). The best and effective way:
String.prototype.escapeJSON = function() {
var result = \"\";
for (var i = 0; i < this.length; i++)
{
var ch = this[i];
switch (ch)
{
case \"\\\\\": ch = \"\\\\\\\\\"; break;
case \"\\\'\": ch = \"\\\\\'\"; break;
case \"\\\"\": ch = \'\\\\\"\'; break;
case \"\\&\": ch = \"\\\\&\"; break;
case \"\\t\": ch = \"\\\\t\"; break;
case \"\\n\": ch = \"\\\\n\"; break;
case \"\\r\": ch = \"\\\\r\"; break;
case \"\\b\": ch = \"\\\\b\"; break;
case \"\\f\": ch = \"\\\\f\"; break;
case \"\\v\": ch = \"\\\\v\"; break;
default: break;
}
result += ch;
}
return result;
};