【发布时间】:2012-03-04 08:57:14
【问题描述】:
我遇到了一个问题,正在寻找解决问题的最佳方法。
我接手开发了一个网站,其中后端是用 Perl 编写的,而前端则广泛使用 javascript。
客户端定期从后端接收数百个跟踪对象的更新。这些对象通过 javascript 映射到谷歌地图上。对象哈希(由 javascript 解析)包含有关对象的大量信息,例如位置、描述和各种状态变量。
有些数据是字符串形式,有些是数字形式。
问题是,在将数据推送到客户端 javascript 的过程中,所有值都变成了字符串。因此,在 javascript 中,例如,如果我测试一个值是否为正,即使值为 0,测试也会成功,因为该值实际上是“0”而不是 0。
在服务器端,数据使用 JSON::XS 编码如下;
sub process_json {
my $self = shift;
return if( $self->{processed} );
$self->{processed} = 1;
if( $self->{requestrec}->status =~ /^3/ )
{
return $self->{requestrec}->status;
}
$self->{data}->{session} = {
id => $self->session->id,
user => $self->session->{data}->{__user},
};
use utf8;
my $output;
eval { $output = JSON::XS->new->utf8->encode( $self->{data} ); };
if($@)
{
use Carp;
confess($@);
}
$self->discard_request_body();
$self->req->content_type('application/json; charset=utf-8');
$self->req->headers_out->set( 'Expires' => 'Thu, 1 Jan 1970 00:00:00 GMT' );
my $out_bytes = encode( 'UTF-8', $output );
$self->req->headers_out->set( 'Content-Length' => length $output );
$self->req->print($output) unless( $self->req->header_only() );
delete $self->{session}->{data}->{errors}
if( exists $self->{session}->{data}->{errors} );
delete $self->{session}->{data}->{info}
if( exists $self->{session}->{data}->{info} );
} ## end of: sub process_json
在客户端,数据用JSON.parse解码如下;
function http_process (req, callback, errorfn) {
if (req.readyState == 4) {
this.activerequest = null;
if (req.status != 200 && req.status != 0 && req.status != 304 && req.status != 403) {
if (errorfn) { return errorfn(req); } else { dialogue("Server error", "Server error " + req.status); }
if (req.status == 400) { dialogue("ERROR","Session expired"); this.failed = 1;
} else if (req.status == 404) { dialogue("ERROR", "Server error (404)"); this.failed = 1;
} else if (req.status == 500) { dialogue("ERROR", "Server error (500)"); this.failed = 1; }
} else {
if (callback) {
if (req.responseText) {
lstatus("Loaded (" + req.responseText.length + " bytes)");
warn("Received " + req.responseText.length + " bytes");
try {
var obj = JSON.parse(req.responseText);
} catch(e) {
warn(e);
warn(req.responseText);
}
callback( obj );
} else {
callback({});
}
}
}
}
}
任何人都可以找到解决此问题的有用方法吗? Perl 不是强类型的,JSON::XS 只是将数字数据解析为字符串而不是数字。我试图向 JSON.parse 添加一个 reviver(参见下面的代码) - 但是它不起作用(它正确处理大部分数据,但由于各种消息(例如 non_object_property_call 或 undefined_method)而不断失败。
无论如何,最好在服务器端处理解析数据以确保正确类型的工作。谁能看到如何有效地实现这一目标?
function toNum(key, value) {
/*make sure value contains an integer or a float not a string */
/*TODO: This seems VERY inefficient - is there a better way */
if (value instanceof Object) return;
if (value instanceof Array) return;
var intRE = /^\d+$/;
var floatRE = /^\d*\.\d+$/;
if(value.match(intRE)) {
value = parseInt(value);
return value;
}
if(value.match(floatRE)) {
value = parseFloat(value);
return value;
}
}
【问题讨论】:
-
啊 - 我刚刚修好了我的复活器,它必须如下; function toNum(key, value) { /*确保 value 包含整数或浮点数而不是字符串 */ /*TODO: 这似乎非常低效 - 有没有更好的方法 */ if (value instanceof String) { var intRE = /^\d+$/; var floatRE = /^\d*\.\d+$/; if(value.match(intRE)) { value = parseInt(value);返回值; } if(value.match(floatRE)) { value = parseFloat(value);返回值; } } else { 返回值; } } 但如果存在,仍然希望找到更好的方法?
-
好的,事实证明,在服务器端解决此问题的唯一方法(我能找到)是解析数据对象,查找任何看起来像整数或浮点数的东西并添加 0给它。即 $val += 0。然后我在 JS 端得到正确的值。
标签: javascript json perl