18

I have to send characters like ü to the server as unicode character but as an ASCII-safe string. So it must be \u00fc (6 characters) not the character itself. But after JSON.stringify it always gets ü regardless of what I've done with it.

If I use 2 backslashes like \\u00fc then I get 2 in the JSON string as well and that's not good either.

Important constraint: I can't modify the string after JSON.stringify, it's part of the framework without workaround and we don't want to fork the whole package.

Can this be done? If so, how?

starball
  • 20,030
  • 7
  • 43
  • 238
indriq
  • 372
  • 1
  • 4
  • 10
  • Have you read this - http://stackoverflow.com/a/25198712/2524202 – SK. Jul 27 '15 at 09:29
  • 2
    Why do you need the `ü` as `\uxxxx` representation? The `JSON.stringify` creates a correctly encoded JSON representation, so every server-side JSON parser should be able to correctly decode it. – t.niese Jul 27 '15 at 09:49
  • not the why is the question. that is how the request must be sent, period. :) – indriq Jul 27 '15 at 13:26
  • @Mike, of course I've read all of those questions and answers, but it seems you did read mine question well enough... :) That's the problem what is in that thread I want to avoid that. – indriq Jul 27 '15 at 13:28
  • And someone please explain why the -1? I'm really curious... – indriq Jul 27 '15 at 13:39

3 Answers3

54

If, for some reason, you want your JSON to be ASCII-safe, replace non-ascii characters after json encoding:

var obj = {"key":"füßchen", "some": [1,2,3]}

var json = JSON.stringify(obj)
json  = json.replace(/[\u007F-\uFFFF]/g, function(chr) {
    return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4)
})

document.write(json);
document.write("<br>");
document.write(JSON.parse(json));
georg
  • 211,518
  • 52
  • 313
  • 390
  • Nice, much more elegant than the for loop – Danny Sullivan Jul 27 '15 at 12:32
  • yes, I know this but I can't modify the string after stringify – indriq Jul 27 '15 at 13:36
  • 1
    @indriq: I'm afraid this is not possible. THere's no way you can affect how stringify encodes strings. – georg Jul 27 '15 at 14:38
  • 1
    I know stackoverflow community does not appreciate comment with no additional useful information, but... You resolverd my pain of the day!) Thanks for that! – NikitOn Dec 27 '16 at 14:20
  • 1
    Can't the lower bound be 0080? – androidguy Dec 26 '18 at 09:25
  • I would agree with @androidguy in that the lower range should be increased based on http://www.asciitable.com/ and the `DEL` character being code 127 (i.e. 0x007F). – Tranzium Oct 21 '20 at 16:38
  • Can't replace zero-width space. `\u200B` – user3471194 Oct 10 '22 at 21:59
  • @androidguy I believe the 0x007f lower bound may be OK. Python's `json.dumps` encodes non-ASCII characters, and it encodes 0x7f. I ran the following in Python `json.dumps("A"+"ß"+chr(0x7f)+chr(0x200B)+chr(0x41)+chr(0x7e))` and it output `'"A\\u00df\\u007f\\u200bA~"'`, the same as the script above – Charles L. Jan 19 '23 at 19:02
1

This should get you to where you want. I heavily based this on this question: Javascript, convert unicode string to Javascript escape?

var obj = {"key":"ü"};
var str1 = JSON.stringify(obj);
var str2 = "";
var chr = "";
for(var i = 0; i < str1.length; i++){
    if (str1[i].match(/[^\x00-\x7F]/)){
        chr = "\\u" + ("000" + str1[i].charCodeAt(0).toString(16)).substr(-4);
    }else{
        chr = str1[i];
    }
    str2 = str2 + chr;
}  
console.log(str2)

I would recommend though that you look into @t.niese comment about parsing this server side.

Community
  • 1
  • 1
Danny Sullivan
  • 3,626
  • 3
  • 30
  • 39
0

Depending on the exact scenario, you can affect the behavior of JSON.stringify by providing a toJSON method as detailed here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior

If an object has a toJSON method that is a function, then calling JSON.stringify on that will use the result of that method rather than the normal serialization. You could combine this with the approaches mentioned in other answers to get the result you want, even if a library doesn't naturally provide any hooks for customization.

(Of course, its possible that a third-party library is itself doing something that overrides this behavior.)

starwed
  • 2,536
  • 2
  • 25
  • 39