Here a solution that handle also the escaping of all UNICODE Control Characters generating a fully valid JSON string (+ the replacement regex is only one):
const chars = { "\"": "\\\"", "\\": "\\\\", "\/": "\\/", "\u0000": "\\u0000", "\u0001": "\\u0001", "\u0002": "\\u0002", "\u0003": "\\u0003", "\u0004": "\\u0004", "\u0005": "\\u0005", "\u0006": "\\u0006", "\u0007": "\\u0007", "\u0008": "\\u0008", "\u0009": "\\u0009", "\u000A": "\\u000A", "\u000B": "\\u000B", "\u000C": "\\u000C", "\u000D": "\\u000D", "\u000E": "\\u000E", "\u000F": "\\u000F", "\u0010": "\\u0010", "\u0011": "\\u0011", "\u0012": "\\u0012", "\u0013": "\\u0013", "\u0014": "\\u0014", "\u0015": "\\u0015", "\u0016": "\\u0016", "\u0017": "\\u0017", "\u0018": "\\u0018", "\u0019": "\\u0019", "\u001A": "\\u001A", "\u001B": "\\u001B", "\u001C": "\\u001C", "\u001D": "\\u001D", "\u001E": "\\u001E", "\u001F": "\\u001F", "\u007F": "\\u007F", "\u0080": "\\u0080", "\u0081": "\\u0081", "\u0082": "\\u0082", "\u0083": "\\u0083", "\u0084": "\\u0084", "\u0085": "\\u0085", "\u0086": "\\u0086", "\u0087": "\\u0087", "\u0088": "\\u0088", "\u0089": "\\u0089", "\u008A": "\\u008A", "\u008B": "\\u008B", "\u008C": "\\u008C", "\u008D": "\\u008D", "\u008E": "\\u008E", "\u008F": "\\u008F", "\u0090": "\\u0090", "\u0091": "\\u0091", "\u0092": "\\u0092", "\u0093": "\\u0093", "\u0094": "\\u0094", "\u0095": "\\u0095", "\u0096": "\\u0096", "\u0097": "\\u0097", "\u0098": "\\u0098", "\u0099": "\\u0099", "\u009A": "\\u009A", "\u009B": "\\u009B", "\u009C": "\\u009C", "\u009D": "\\u009D", "\u009E": "\\u009E", "\u009F": "\\u009F" }; export const escapeJsonString = str => str.replace(/[\"\\\/\u0000-\u001F\u007F\u0080-\u009F]/g, match=>chars[match]);
Note that \b \f \n \r \t are not listed as already matched by \u0008 \u000C \u000A \u000D \u0009 respectively.
The proposed code is expected to be in a JS module due to the bulky chars replacement map, but you can also remove the export and add it all in a function if you prefer.