我正在将JSON从我的Javascript应用程序发布到此API,如果您将它发送给双打,则会有不同的行为。我只是使用JSON.stringify
来构建我的请求主体。我总是想送双打。但是当我有Javascript数字是不可或缺的时候,JSON.stringify
会这样做:
> JSON.stringify({x: 1.0});
'{"x":1}'
那个朴实无华的1进入API,其他服务器认为它是一个int,我得到整数行为,我不想要。是否有任何已知的黑客在Javascript中使用我的JSON加倍?
答案 0 :(得分:1)
JSON(以及一般的JavaScript)不区分不同的数字类型;只有"数字"。因此,这有点超出了JSON.stringify
的范围。
这是一个非常糟糕的解决方法:
JSON.stringify({x: 1.0}).replace(
/("(?:[^"\\]|\\.)*")|[\[:,]\s*-?\d+(?![\d.eE])/g,
function (m0, m1) { return m1 || m0 + '.0'; }
)
这个(相当大的锤子)使用正则表达式将.0
添加到所有不具有.
并且不属于带引号的字符串的数字中。
答案 1 :(得分:1)
另一种方法:构建JSON.stringify
的自定义版本,它将始终输出带小数点的数字。
这只是从Mozilla JSON documentation获取一个示例实现,并修改处理数字的代码行:
window.JSON.stringifyDecimal = (function(){
var toString = Object.prototype.toString;
var isArray = Array.isArray || function (a) { return toString.call(a) === '[object Array]'; };
var escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'};
var escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); };
var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g;
return function stringify(value) {
if (value == null) {
return 'null';
} else if (typeof value === 'number') {
// Ensure decimal point is present
return isFinite(value) ? value.toString() + ( Number.isInteger( value ) ? '.0' : '' ) : 'null';
} else if (typeof value === 'boolean') {
return value.toString();
} else if (typeof value === 'object') {
if (typeof value.toJSON === 'function') {
return stringify(value.toJSON());
} else if (isArray(value)) {
var res = '[';
for (var i = 0; i < value.length; i++)
res += (i ? ', ' : '') + stringify(value[i]);
return res + ']';
} else if (toString.call(value) === '[object Object]') {
var tmp = [];
for (var k in value) {
if (value.hasOwnProperty(k))
tmp.push(stringify(k) + ': ' + stringify(value[k]));
}
return '{' + tmp.join(', ') + '}';
}
}
return '"' + value.toString().replace(escRE, escFunc) + '"';
};
})();
答案 2 :(得分:0)
使用JSON,您有两个派对:作者和读者。在您的情况下,作者是您的请求,您正在使用JSON.stringify
生成JSON字符串,而读者是API(我不知道它用于解析字符串的内容到JSON对象)。您需要双方都能够理解1.0
应保持原样,因为它是双精度而不是整数。
JSON字符串本身只是文本,并保留您给它的任何内容。将JSON.stringify
转换为1.0
的是1
,因此您可以轻松地手动创建JSON字符串,而不是使用JSON.stringify
:
var text = JSON.stringify({x: 1.0}); //JSON string will be {"x": 1}
var text = '{"x": 1.0}'; //JSON string will be exactly {"x": 1.0}
但是,即使您这样做,也需要另一方(即API)将值1.0
解析为double,而不是整数。这是你的控制吗?例如,JavaScript JSON.parse
函数会将1.0
解析为1
,与JSON.stringify
完全相同:
var obj = JSON.parse('{"x": 1.0}');
alert(obj.x); //It prints 1, even though we gave it 1.0