【问题标题】:iOS to web server via POST - string gets cut off?iOS 通过 POST 到 Web 服务器 - 字符串被切断?
【发布时间】:2012-12-27 14:40:35
【问题描述】:

我正在尝试从我的 iOS 应用程序将序列化对象发送到 Web 服务器,并且通常一切正常。我试过发送一个巨大的字符串,它在服务器上就很好了。但是当我将序列化对象发送到服务器时,字符串会被切断。我已经从我的应用程序中记录了字符串 - 它就在那里。我尝试将相同的字符串写入我的网络服务器上的文件,但它以最奇怪的方式被切断了。

可能是什么原因?我怀疑这与编码有关。这是我将数据发送到服务器的方式:

+ (void)postRequestWithData:(id)data toURL:(NSURL *)url {
    // Prepare data
    NSData *postData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:nil];
    NSString *postDataString = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
    NSString *requestString = [NSString stringWithFormat:@"sales=%@", postDataString];
    NSString *postLength = [NSString stringWithFormat:@"%d", [requestString length]];

    // Make the request
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:url];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:[requestString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    // Error reporting
    if (!connection) {
        NSLog(@"Could not make a connection!");
    }
}

其中 (id)data 是一个字典数组。

这是我在服务器中处理它的方式:

<?php
    $sales = $_POST['sales'];
    $myFile = "testFile.txt";
    $fh = fopen($myFile, 'w') or die("can't open file");
    fwrite($fh, $sales);
    fclose($fh);
?>

【问题讨论】:

  • @"Current-Type" 应该是 @"Content-Type"...
  • 啊,谢谢。不过还是不行。
  • 另外,[requestString length] 应该是 strlen([requestString UTF8String]
  • 尝试使用与漂亮打印不同的序列化方法。我想漂亮的打印将包括换行符,这样可能会导致 PHP 代码过早终止字符串。
  • @Jasarien 同意,我应该使用哪一个?方法有数百种,我一个都不熟悉。

标签: ios json post


【解决方案1】:

您应该根据application/x-www-form-urlencode 转义您的 URL(查询)字符串。为此有一个 NSString 函数:

- (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding

据此,您的代码应如下所示:

NSData *postData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted error:nil];
NSString *postDataString = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
NSSztring *escapedDataString = [postDataString stringByAddingPercentEscapesUsingEncoding:NSUTF8Encoding]
NSString *requestString = [NSString stringWithFormat:@"sales=%@", escapedDataString];
NSString *postLength = [NSString stringWithFormat:@"%d", [requestString length]];

【讨论】:

    【解决方案2】:

    您需要先对您的 postDataString 进行 URL 编码。为此,您可以使用 Core Foundation 函数CFURLCreateStringByAddingPercentEscapes

    NSString *encoded = CFBridgingRelease( CFURLCreateStringByAddingPercentEscapes( kCFAllocatorDefault, (__bridge CFStringRef)originalString, NULL, NULL, kCFStringEncodingUTF8 ) );
    

    NULL 两个参数都控制哪些字符应该被编码,哪些应该被保留。为两者传递 NULL 会转义 URL 中所有无效的字符。请注意,我在这里假设为 ARC。

    您的 Content-Length 计算也是错误的。您需要从 NSData 对象中获取长度,而不是字符串。

    【讨论】:

    • 我刚刚通过手动替换字符串中的 & 符号解决了这个问题。这个函数 CFURLCreateStringByAddingPercentEscapes 能做到吗?我问是因为我仍然不知道如何实现它:) 如果你能告诉我我可以检查你的答案。
    猜你喜欢
    • 2014-03-07
    • 2013-12-06
    • 2012-11-22
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多