6

JSON is not a subset of JavaScript. I need my output to be 100% valid JavaScript; it will be evaluated as such -- i.e., JSON.stringify will not (always) work for my needs.

Is there a JavaScript stringifier for Node?

As a bonus, it would be nice if it could stringify objects.

2 Answers 2

12

You can use JSON.stringify and afterwards replace the remaining U+2028 and U+2029 characters. As the article linked states, the characters can only occur in the strings, so we can safely replace them by their escaped versions without worrying about replacing characters where we should not be replacing them:

JSON.stringify('ro\u2028cks').replace(/\u2028/g,'\\u2028').replace(/\u2029/g,'\\u2029')
Sign up to request clarification or add additional context in comments.

Comments

1

From the last paragraph in the article you linked:

The solution

Luckily, the solution is simple: If we look at the JSON specification we see that the only place where a U+2028 or U+2029 can occur is in a string. Therefore we can simply replace every U+2028 with \u2028 (the escape sequence) and U+2029 with \u2029 whenever we need to send out some JSONP.

It’s already been fixed in Rack::JSONP and I encourage all frameworks or libraries that send out JSONP to do the same. It’s a one-line patch in most languages and the result is still 100% valid JSON.

9 Comments

I read that bit, but I can't quite figure it out. JSON.stringify('ro\u2028cks'.replace('\u2028','\\u2028').replace('\u2029','\\u2029')) gives "ro\\u2028cks" -- i.e., it's double escaped now. I don't want to have to reimplement the entire JSON.stringify method to accomplish this.
@Mark Me neither - but you can post a much more specific question regarding unicode escaping that anyone who knows JS can help you with, instead of something only node developers may have expertise in.
@Mark note I would do this as a separate question; they are distinct enough and there may be a better answer to this one than what I have posted (ideally simply a feature in the JSON parser that encapsulates this.)
@Mark You'd need to turn it into a JSON string first, and then replace the unicode characters: JSON.stringify('ro\u2028cks').replace('\u2028','\\u2028').replace('\u2029','\\u2029')
@Mark: actually, that replace is insufficient; it will only replace the first occurrence of each character. Using a regexp with the global flag would do the trick: JSON.stringify('ro\u2028cks').replace(/\u2028/g,'\\u2028').replace(/\u2029/g,'\\u2029')
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.