【问题标题】:How to preserve numeric fields in JSON.stringify如何在 JSON.stringify 中保留数字字段
【发布时间】:2016-08-01 16:30:20
【问题描述】:

我的代码采用表单字段并将它们转换为适合传递给 REST API(特别是马拉松 REST API)的 JSON 字符串。问题是 JSON.stringify 双引号所有表单字段值,即使是数字,这会导致 ajax 调用失败。这是我的代码生成的字符串:

{"id":"basic-1","cpus":"0","mem":"32","instances":"1","cmd":"while [ true ] ; do echo 'Hello Marathon' ; sleep 5 ; done"}

mem、cpus 和 instances 值不应被双引号,因为它们是数字。

data: JSON.stringify($('form').MytoJson());

MytoJson 是一个序列化表单字段的函数。这工作正常。问题是 JSON.stringify 将引号放在键和所有值周围,包括数值,这导致 ajax 调用失败。

JSON.stringify 函数有两个参数。第一个参数是替换函数,可以是函数或数组。考虑这个替换函数:

function replacer(key, value) {
    if (typeof value === "string") {
        return undefined;
    }
    return value;
}
JSON.stringify($('form').MytoJson(), replacer);

我想将此替换函数修改为不引用数值。我想知道我是否使用 HTML5 表单属性来区分字符串和数字表单字段?考虑这个表单域:

<input id="cpus" type="number" name="cpus" value="0.1" />

如何在替换函数中使用该字段具有 type="number" 属性这一事实?当表单字段为数字类型时,我想修改替换函数以不引用值。

【问题讨论】:

  • 这不应该导致 ajax 调用失败 - 我猜你正在使用 POST 或 PUT - 这仍然应该将数据发送到你的服务 - 你需要做的是在你的服务然后将这些字符串值转换为数字,然后再传递给您的数据库。在将数字发布到 restful 服务之前对数字进行字符串化是标准程序。

标签: javascript marathon


【解决方案1】:

为了将字符串化的字符串转回数据,您可以使用JSON.parse(stringifyedString);

例如,仅从字符串中删除引号不会将 "5" 转换为 Number。它只会用字符 5 创建一个字符串。

【讨论】:

  • 好点。我现在使用parseFloat() 在我的reducer 函数中将字符串转换为浮点数。请参见上文。
【解决方案2】:

我不是 100%,但我认为问题是由读取表单字段值的代码引起的 - 即它正在将值作为字符串读取(它们是)。

您需要做的是将任何数值转换为实际的 JS Number。试试下面的replacer函数:

function replacer( key, value ) {

    var ret = ( value === value * 1 )
            ? value * 1
            : value;

    return ret;

}

这应该检查每个值是否为数字,如果是则将其转换为Number

【讨论】:

  • 你是对的。关键是将数字字段转换为浮点数。我很惊讶没有库可以做到这一点 - 查看表单字段类型并将数据转换为 JSON 字符串的适当类型。或者也许我只是没有找到它。
【解决方案3】:

这是解决方案。我已经修改了替换函数以使用 HTML5 表单字段类型来区分应该引用或不引用的表单字段。

function replacer(key, value) {
    //console.log(typeof($(eval('\'#' + key + '\'')).attr('type')));
    if ($(eval('\'#' + key + '\'')).attr('type') == null) {
        return value;
    }
    return parseFloat(value);
} 

然后在我的 ajax 代码中:

 data: JSON.stringify($('form').MytoJson(), replacer);

似乎标准“文本”输入字段的“类型”属性未定义,但在类型为“数字”时已定义。我正在使用它。

如果类型属性未定义,我只返回 JSON 字符串中包含并双引号的值。但是如果定义了类型属性,那么我将值转换为浮点数。它包含在未引用的 JSON 字符串中。 目前这是一个可行的解决方案,但我相信我必须在不久的将来重新访问它。

【讨论】:

    【解决方案4】:

    你需要给JSON.stringify()一个替换函数来转换结果。
    像这样:

    JSON.stringify(x, (key, value) => (isNaN(value) ? value : +value))
    

    isNan() 函数接受一个数字并检查它是否为NaN
    如果你传递给它的不是number 类型,它会被转换为number 或NaN。

    如果value 确实包含数字,则Unary plus +valuevalue 返回为number,否则返回NaN。

    【讨论】:

      猜你喜欢
      • 2017-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 2015-08-31
      • 1970-01-01
      • 2016-05-02
      相关资源
      最近更新 更多