2015-10-13 35 views
0

我从我的Javascript应用程序发布JSON到这个API,如果你把它发送给双精度型和整型,它的行为会有所不同。我只是用JSON.stringify来构建我的请求体。我总是想发送双打。但是,当我有是一体的Javascript数字,JSON.stringify做到这一点:我可以让一个JSON字符串化的对象有一个字段,其值是一个双重的Javascript?

> JSON.stringify({x: 1.0}); 
'{"x":1}' 

这缦1进入到其他服务器认为它是一个int的API,而我得到的整数的行为,这是我不希望。是否有任何已知的黑客得到在我的JSON在JavaScript中的双重?

+7

在JSON唯一数字型十进制浮点。您的值'1.0'完全等同于'1'。问题不在于'JSON.stringify()',而是您的服务器API错误地解释了JSON。 – Pointy

+0

迷人!所以Elasticsearch(见https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-core-types.html的第二句)只是傻瓜做的破解软件。我一直都很怀疑。无论如何,我坚持使用它,所以希望我能找到一些破解在JavaScript中做到这一点。 –

+1

这并不准确。没有任何其他上下文来指示精度(这不是JSON本身可以做的事情)的值“1.0”与**值“1”完全相同。 – Pointy

回答

1

JSON(和JavaScript一般)不区分不同的数字类型;只有“数字”。因此,这有点超出JSON.stringify的范围。

这里有一个很可怕的解决方法:

JSON.stringify({x: 1.0}).replace(
    /("(?:[^"\\]|\\.)*")|[\[:,]\s*-?\d+(?![\d.eE])/g, 
    function (m0, m1) { return m1 || m0 + '.0'; } 
) 

这(相当大铁锤)使用正则表达式来添加.0到不已经有一个.和不带引号的字符串的一部分所有数字。

0

随着JSON,你有两方:作家和读者。在你的情况下,作者是你的请求,你使用JSON.stringify来生成JSON字符串,而读者是API(我不知道它是如何将字符串解析回JSON对象的)。您需要双方都能够明白,1.0应该保持不变,因为它是一个双精度不是整数。

JSON字符串本身就是文本,并保持你给它的任何东西。它是一种将1.01JSON.stringify,这样你就可以轻松地手动创建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.01酷似JSON.stringify做:

var obj = JSON.parse('{"x": 1.0}'); 
alert(obj.x); //It prints 1, even though we gave it 1.0 
+1

为什么会有人投票呢? – Pointy

+0

@点我不知道。感谢您回复它。应该有一个限制,所以不发表评论就不能投票。这个网站的目标是我们都可以学习,而我们不知道为什么通过投票而不学什么。 –

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) + '"'; 
    }; 
})(); 
相关问题