JSON中的撇号在服务器上导致错误

时间:2022-08-26 17:01:30

I have a string that I'm doing a JSON.stringify(str) on in Javascript. The string is L'Oreal.

我有一个字符串,我在Javascript中执行JSON.stringify(str)。字符串是欧莱雅。

However, as this variable gets passed around before the JSON.stringify happens, its value becomes

但是,由于这个变量在JSON之前传递。弦化发生,它的值变成

L& #39;Oreal(without the space between & and #), and the resulting JSON string that i send to the server is being recognized as potentially dangerous and I get a server side error.

欧莱雅(没有&和#之间的空格)和我发送到服务器的JSON字符串被认为是潜在的危险,我得到了服务器端错误。

My question is, how do I avoid the apostrophe getting replaced by <&#39>; before the stringify call, or an alternate way to solve this?

我的问题是,如何避免撇号被<'>取代;在stringify调用之前,或者解决这个问题的另一种方法?

EDIT 1: Here's some code that is causing this, its quite basic -

编辑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);

I tried to build a jsFiddle but I do not see this happening there in this very basic example which mimics the # of times the string gets assigned in the actual code.

我尝试构建一个jsFiddle,但是在这个非常基本的示例中,我没有看到这种情况发生,这个示例模拟了字符串在实际代码中被赋值的次数。

EDIT 2: I know why this is happening now. We HTML Encode the data when it comes from the server to avoid XSS injection. While it displays alright, when I convert this data to JSON, it results in ill-formed JSON which the server recognizes as potentially dangerous and throws an exception.

编辑2:我知道现在为什么会这样。我们对来自服务器的数据进行HTML编码,以避免XSS注入。当它显示正常时,当我将数据转换为JSON时,它会导致格式不佳的JSON,服务器认为这是潜在的危险,并抛出异常。

Server-side code (.Net C#)- WebUtility.HtmlEncode(Data);

(服务器端代码。净c#)——WebUtility.HtmlEncode(数据);

Still don't know what a good way to handle this might be.

仍然不知道如何处理这个问题。

2 个解决方案

#1


0  

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);

You can use a regular expression to sniff out the special character code and replace it back before stringifying it. NOTE: the "g" in the regex above makes the search global so it will replace any instance of "'". The above code should work. Here is a jsfiddle demonstrating. http://jsfiddle.net/pJD9X/1/

您可以使用正则表达式来嗅出特殊的字符代码,并在对其进行绑定之前将其替换回原来的代码。注意:上面regex中的“g”使搜索成为全局的,因此它将替换“'”的任何实例。上面的代码应该可以工作。这是一个小提琴演示。http://jsfiddle.net/pJD9X/1/

EDIT: Alternate whitelist approach. You could possibly create a whitelist of special characters and take an approach that is similar to how underscor.js actually encodes stuff. Only instead of encoding you will be decoding. NOTE: this is possibly a dangerous solution because it allows your code to decode special characters

编辑:替代白名单的方法。您可以创建一个特殊字符的白名单,并采取类似于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);

#2


0  

While the solution that Mike gave will work fine for isolated cases, in my situation the user could enter information with any special characters and there's no way to predict a set of special characters that will be used.

虽然Mike给出的解决方案对于孤立的情况来说是可行的,但是在我的情况下,用户可以输入任何特殊字符的信息,而且无法预测将要使用的一组特殊字符。

In order to over come this, I'm manually decoding each value before JSONifying it -

为了解决这个问题,我在对每个值进行jsonialize之前都要手工解码

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);

#1


0  

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);

You can use a regular expression to sniff out the special character code and replace it back before stringifying it. NOTE: the "g" in the regex above makes the search global so it will replace any instance of "'". The above code should work. Here is a jsfiddle demonstrating. http://jsfiddle.net/pJD9X/1/

您可以使用正则表达式来嗅出特殊的字符代码,并在对其进行绑定之前将其替换回原来的代码。注意:上面regex中的“g”使搜索成为全局的,因此它将替换“'”的任何实例。上面的代码应该可以工作。这是一个小提琴演示。http://jsfiddle.net/pJD9X/1/

EDIT: Alternate whitelist approach. You could possibly create a whitelist of special characters and take an approach that is similar to how underscor.js actually encodes stuff. Only instead of encoding you will be decoding. NOTE: this is possibly a dangerous solution because it allows your code to decode special characters

编辑:替代白名单的方法。您可以创建一个特殊字符的白名单,并采取类似于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);

#2


0  

While the solution that Mike gave will work fine for isolated cases, in my situation the user could enter information with any special characters and there's no way to predict a set of special characters that will be used.

虽然Mike给出的解决方案对于孤立的情况来说是可行的,但是在我的情况下,用户可以输入任何特殊字符的信息,而且无法预测将要使用的一组特殊字符。

In order to over come this, I'm manually decoding each value before JSONifying it -

为了解决这个问题,我在对每个值进行jsonialize之前都要手工解码

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);