Апостроф в JSON вызывает ошибки на сервере

У меня есть строка, в которой я делаю JSON.stringify(str) в Javascript. Строка L'Oreal.

Однако, поскольку эта переменная передается раньше, чем происходит JSON.stringify, ее значение становится

L& O;Oreal(без пробела между & и #) и полученная строка JSON, которую я отправляю на сервер, распознается как потенциально опасная, и я получаю ошибку на стороне сервера.

У меня вопрос: как избежать замены апострофа на <& # 39>; перед вызовом stringify или альтернативным способом решения этой проблемы?

РЕДАКТИРОВАТЬ 1: Вот некоторый код, который вызывает это, его довольно простой -

for (var rowIndex = 0; rowIndex < numrows; rowIndex++)
{
     var cellValues = new Array();
     for (var cellIndex=0; cellIndex < numCols; cellIndex++)
     {
          cellValues[cellIndex] = someInputArray[cellIndex]; //One of the values that gets populated here inlcudes the word L'Oreal
     }
     rowValues[rowIndex] = cellValues; //After this assignment, rowValues[0][3] which was earlier L'Oreal becomes L&#39;Oreal
}

var jsonToSend = JSON.stringify(rowValues);

Я пытался построить jsFiddle, но я не вижу, чтобы это происходило в этом очень простом примере, который имитирует количество раз, которое строка присваивается в реальном коде.

РЕДАКТИРОВАТЬ 2: Я знаю, почему это происходит сейчас. Мы HTML кодируем данные, когда они поступают с сервера, чтобы избежать внедрения XSS. Хотя все отображается нормально, когда я конвертирую эти данные в JSON, это приводит к неправильному формату JSON, который сервер распознает как потенциально опасный, и выдает исключение.

Серверный код (.Net C#)- WebUtility.HtmlEncode(Data);

До сих пор не знаю, какой хороший способ справиться с этим может быть.

2 ответа

Решение
var str = "This is a test string with L&#39;Oreal in it.";
var regex = /&#39;/g;
var output = JSON.stringify(str.replace(regex, "'"));
$('#test').html(output);

Вы можете использовать регулярное выражение, чтобы выяснить код специального символа и заменить его обратно перед тем, как его преобразовать в строку. ПРИМЕЧАНИЕ: "g" в приведенном выше регулярном выражении делает поиск глобальным, поэтому он заменит любой экземпляр "". Приведенный выше код должен работать. Вот демонстрация jsfiddle. http://jsfiddle.net/pJD9X/1/

РЕДАКТИРОВАТЬ: Альтернативный подход белого списка. Вы могли бы создать белый список специальных символов и использовать подход, аналогичный тому, как underscor.js на самом деле кодирует вещи. Только вместо кодирования вы будете декодировать. ПРИМЕЧАНИЕ. Возможно, это опасное решение, поскольку оно позволяет вашему коду декодировать специальные символы.

var str = "This is a test string with L&#39;Oreal in it and an ampersand &#38; in it";
var whiteList = {
    "&#39;":"'",
    "&#38;":"&"
};
var specialCharDecoder = /&#39;|&#38;/g;
function htmlDecode (string) {
    return ('' + string).replace(specialCharDecoder, function (match) {
       return whiteList[match]; 
    });
}
var output = htmlDecode(str);

Хотя решение, предложенное Майком, будет отлично работать в отдельных случаях, в моей ситуации пользователь может вводить информацию с помощью любых специальных символов, и нет способа предсказать набор специальных символов, которые будут использоваться.

Чтобы преодолеть это, я вручную декодирую каждое значение перед его JSON ном -

for (var rowIndex = 0; rowIndex < numrows; rowIndex++)
{
    var cellValues = new Array();
    for (var cellIndex=0; cellIndex < numCols; cellIndex++)
    {//FIX BELOW
        cellValues[cellIndex] = $('<div />').html(someInputArray[cellIndex]).text(); //manually decode
    }
    rowValues[rowIndex] = cellValues; 
}

var jsonToSend = JSON.stringify(rowValues);
Другие вопросы по тегам