【问题标题】:Send umlauts from Node.js to iOS从 Node.js 向 iOS 发送变音符号
【发布时间】:2013-07-05 13:46:44
【问题描述】:


我不知道这是 Node.js 还是 iOS 问题,但是当我尝试发送包含变音符号(ä、ö 和 ü)的 JSON 对象时,设置的内容长度似乎是错误的。

这是我的设置:

我的 Node.js 服务器通过以下方式发送数据:

[..mongodb request..].toArray(function(err, result) {
    res.setHeader('Content-Type', 'application/json');
    var body = JSON.stringify(result);

    console.log(body);
    console.log(body.length);

    res.setHeader('charset', 'utf8');
    res.setHeader('Content-Length', body.length);
    res.end(body);
});

这会产生以下对象:

[
{
    "_id": "51da7eb5d5f9ad77302a26c6",
    "loc": [
        53.560994,
        9.929796
    ],
    "street": "Kühnehöfe 25",
    "time": 1373273781535
},
{
    "_id": "51da7eb9d5f9ad77302a26c7",
    "loc": [
        53.561899,
        9.930203
    ],
    "street": "Kühnehöfe 17",
    "time": 1373273785156
}
]

其中(解析为字符串)长度为 215。这也设置为内容长度。

在我的 iOS 项目中,我有以下设置:

-(void)serverRequest {

    // Initialize new mutable data
    NSMutableData *data = [[NSMutableData alloc] init];
    self.receivedData = data;

    // Initialize URL that is going to be fetched.
    NSURL *url = [NSURL URLWithString:@"http://localhost:8000/getSpots"];

    // Initialize a request from a URL
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];

    // Set HTTP method
    [request setHTTPMethod:@"POST"];

    // Initialize post data
    NSDictionary* jsonDict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:coordinate.latitude], @"lat", [NSNumber numberWithFloat:coordinate.longitude], @"lng", accessToken, @"accessToken", nil];//dictionaryWithObjectsAndKeys:coord.latitude, nil]
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict
                                                   options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                                                     error:&error];

    // Set request content type we MUST set this value.
    [request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"content-type"];

    // Set post data of request
    [request setHTTPBody:jsonData];

    // Initialize a connection from request
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    self.connectionGetSpots = connection;

    // Start the connection
    [connection start];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [self.receivedData appendData:data];

    NSLog(@"loading: %d, %lld", [self.receivedData length], dataSize);  // Both 215 (correct)
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    dataSize = [response expectedContentLength];
    NSLog(@"dataSize: %lld", dataSize);  // is 215 (correct)
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
    NSString *responseData = [[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding];
    NSLog(@"rD: %@, %d" ,responseData, [responseData length]);
}

connectionDidFinishLoading 函数记录以下内容:

[
{
    "_id": "51da7eb5d5f9ad77302a26c6",
    "loc": [
        53.560994,
        9.929796
    ],
    "street": "Kühnehöfe 25",
    "time": 1373273781535
},
{
    "_id": "51da7eb9d5f9ad77302a26c7",
    "loc": [
        53.561899,
        9.930203
    ],
    "street": "Kühnehöfe 17",
    "time": 13732737851
,211

如您所见,JSON 对象中有四个变音符号,并且缺少四个字符。如果我添加另一个带有两个变音符号的位置,则会丢失另外两个字符。

我猜某处内容类型设置错误,但我不确定我必须做什么。

【问题讨论】:

  • 您问题中的 JSON 字符串有 315 个字符(不是 215 个)。由于每个变音符号都编码为 2 个 UTF-8 字节,因此内容长度应为 319。
  • 对不起,我发送的原始字符串是:[{"_id":"51da7eb5d5f9ad77302a26c6","loc":[53.560994,9.929796],"street":"Kühnehöfe 25","time":1373273781535},{"_id":"51da7eb9d5f9ad77302a26c7","loc":[53.561899,9.930203],"street":"Kühnehöfe 17","time":1373273785156}] 我已将其格式化以提高可读性
  • 那么,你的字符串有 231 个字节。你的 JS 语句 body.length 返回什么? 字符数 还是字节数(不太可能)?确保在请求中设置字节数组而不是字符串可能会更好。
  • 是的,它返回字符数。
  • 如果我使用encodeURI(body).split(/%..|./).length - 1 而不是body.length,它会起作用。感谢您的帮助

标签: ios node.js


【解决方案1】:

将此用于正确的 UTF-8 长度:

new Buffer(body).length

【讨论】:

  • 不错!并且编码是默认的 UTF-8 ;) 我不是 OP,但是将 Buffer 实例设置为请求的主体不是更好吗? Content-Length 标头是否也明确需要?
  • 谢谢。您必须将 Buffer 转换回 String (toString('utf-8')),所以没有区别。是的,根据我的经验,确实需要“Content-Length”标头。
  • 这就是我要找的。谢谢
猜你喜欢
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
  • 2018-09-06
  • 2010-12-29
  • 1970-01-01
  • 2021-10-27
相关资源
最近更新 更多