Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force JSON.stringify to escape forward slash (i.e. `\/`)

I'm writing a service in nodejs that replaces an existing system written in .NET. The service provides a JSON API, one of the calls returns a date. The Microsoft date format for JSON was/is where 1599890827000 is the milliseconds offset:

/Date(1599890827000)/

The problem I am having is that JSON.stringify (used in res.send and res.json in express) does not escape forward slashes but the existing Microsoft library (System.Web.Script.Serialization.JavaScriptSerializer) expects forward slashes to be escaped.

For example, the client expects JSON like this:

{
  "Expires": "\/Date(1599890827000)\/"
}

But JSON.stringify produces the following:

{
  "Expires": "/Date(1599890827000)/"
}

The second result is perfectly valid but the Microsoft library doesn't like it and fails to parse.

Is there any way I can force Express/Node/JSON to escape forward slashes in JSON.stringify or handle this case?

I could use a regex replacement after running stringify but because of an object caching system we use in the project it would be very hacky to have to convert to JSON before sending to the client instead of letting.

Note: I cannot change the client, only the api service.

like image 380
antfx Avatar asked Feb 07 '23 13:02

antfx


1 Answers

Replacer happens before escaping, leaving you with either:

"/Date(1599890827000)/"

Or:

"\\/Date(1599890827000)\\/"

Realistically you will have to run a string replace on the resulting output:

JSON.stringify(data).replace(/\//g, '\\/');

This means that you won't be able to use the express built in res.json(data) and may need to instead write a function to replace it like:

function dotNetJSONResponse(res, data) {

    var app = res.app;
    var replacer = app.get('json replacer');
    var spaces = app.get('json spaces');
    var body = JSON.stringify(data, replacer, spaces);

    if (!this.get('Content-Type')) {
        res.set('Content-Type', 'application/json');
    }

    return res.send(body.replace(/\//g, '\\/'));
}

Calling it as:

app.get('/url', function (req, res) {
     dotNetJSONResponse(res, data);
});

However, that said, fixing the behaviour in .NET would be the more forward compatible solution.

like image 114
Stuart Wakefield Avatar answered Feb 11 '23 01:02

Stuart Wakefield