【问题标题】:NSURLConnection connecting to server, but not posting dataNSURLConnection 连接到服务器,但不发布数据
【发布时间】:2013-08-30 21:51:32
【问题描述】:

每当我尝试向我的 PHP 服务器发布内容时,我都会收到以下消息。似乎代码正在连接到服务器,但没有返回任何数据,并且发布数据没有通过。它通过我制作的 Java 应用程序运行,所以我可以保证他们的 PHP 没有问题。如果您可以帮助我,或者需要更多代码来帮助我,请提出要求。谢谢。

这是为 NSURLConnection 准备变量的代码:

NSString *phash = [NSString stringWithFormat:@"%d",phashnum];
        [phash stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
name = _nameField.text;
        [name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        email = _emailField.text;
        [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

这是我的 NSURLConnection 的代码:

NSString *urlPath = [NSString stringWithFormat:@"http://54.221.224.251"];
    NSURL *url = [NSURL URLWithString:urlPath];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    NSString *stringdata = [NSString stringWithFormat:@"name=%@&email=%@&phash=%@",name,email,phash];
    NSOperationQueue *queue= [[NSOperationQueue alloc]init];
    NSString *postData = [[NSString alloc] initWithString:stringdata];
    [request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:[postData dataUsingEncoding:NSUTF8StringEncoding]];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if ([data length] > 0 && connectionError==nil){
            NSLog(@"Connection Success. Data Returned");
            NSLog(@"Data = %@",data);
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            int code = [httpResponse statusCode];
            NSString *coder = [NSString stringWithFormat:@"%d",code];
            NSLog(@"%@",coder);
        }
        else if([data length] == 0 && connectionError == nil){
            NSLog(@"Connection Success. No Data returned.");
            NSLog(@"Connection Success. Data Returned");
            NSLog(@"Data = %@",data);
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            int code = [httpResponse statusCode];
            NSString *coder = [NSString stringWithFormat:@"%d",code];
            NSLog(@"%@",coder);
        }
        else if(connectionError != nil && connectionError.code == NSURLErrorTimedOut){
            NSLog(@"Connection Failed. Timed Out");
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            int code = [httpResponse statusCode];
            NSString *coder = [NSString stringWithFormat:@"%d",code];
            NSLog(@"%@",coder);

        }
        else if(connectionError != nil)
        {
            NSLog(@"%@",connectionError);
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
            int code = [httpResponse statusCode];
            NSString *coder = [NSString stringWithFormat:@"%d",code];
            NSLog(@"%@",coder);

        }
    }];

提前致谢。

【问题讨论】:

标签: php ios objective-c http-post nsurlconnection


【解决方案1】:

正如@elk 所说,您应该用+ 替换空格。但是您应该对保留字符进行百分比编码(如RFC2396 中所定义)。

不幸的是,标准的stringByAddingPercentEscapesUsingEncoding 不会百分百转义所有保留字符。例如,如果名称是“Bill & Melinda Gates”或“Bill + Melinda Gates”,stringByAddingPercentEscapesUsingEncoding 将不会完全逃脱 &+(因此 + 将被解释为空格,& 将被解释为分隔下一个 POST 参数)。

改为使用CFURLCreateStringByAddingPercentEscapes,在legalURLCharactersToBeEscaped 参数中提供必要的保留字符,然后用+ 替换空格。例如,您可以定义一个NSString 类别:

@implementation NSString (PercentEscape)

- (NSString *)stringForPostParameterValue:(NSStringEncoding)encoding
{
    NSString *string = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                 (CFStringRef)self,
                                                                                 (CFStringRef)@" ",
                                                                                 (CFStringRef)@";/?:@&=+$,",
                                                                                 CFStringConvertNSStringEncodingToEncoding(encoding)));
    return [string stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}

@end

注意,我主要关心的是 &+ 字符,但 RFC2396(它取代了 RFC1738)将这些附加字符列为保留字符,因此将所有这些保留字符包含在legalURLCharactersToBeEscaped

综合起来,我可能有代码将请求发布为:

NSDictionary *params = @{@"name" : _nameField.text ?: @"",
                         @"email": _emailField.text ?: @"",
                         @"phash": [NSString stringWithFormat:@"%d",phashnum]};

NSURL *url = [NSURL URLWithString:kBaseURLString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[self httpBodyForParamsDictionary:params]];

[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    if (error)
        NSLog(@"sendAsynchronousRequest error = %@", error);

    if (data) {
        // do whatever you want with the data
    }
}];

使用实用方法:

- (NSData *)httpBodyForParamsDictionary:(NSDictionary *)paramDictionary
{
    NSMutableArray *paramArray = [NSMutableArray array];
    [paramDictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) {
        NSString *param = [NSString stringWithFormat:@"%@=%@", key, [obj stringForPostParameterValue:NSUTF8StringEncoding]];
        [paramArray addObject:param];
    }];

    NSString *string = [paramArray componentsJoinedByString:@"&"];

    return [string dataUsingEncoding:NSUTF8StringEncoding];
}

【讨论】:

    【解决方案2】:

    "name=%@&email=%@&phash=%@" 不是正确的 url 编码字符串。每个键值对必须用“&”字符分隔,每个键与其值之间用“=”字符分隔。键和值都通过用“+”字符替换空格进行转义,然后由stringByAddingPercentEscapesUsingEncoding 编码。

    application/x-www-form-urlencoded

    您可以在this blog post 中找到如何做到这一点的食谱。

    【讨论】:

    • 我更新了上面的代码,成功了,服务器接受了。
    • 你能检查上面的代码以确保现在的代码是正确的吗?因为他们是我遇到的另一个单独的问题。
    • 你必须先用'+'替换空格-我猜name是唯一可以包含空格的字符串。
    • 我不能只对空间进行百分比编码吗?并将其设置为 %20?
    • 不,%20 很好,the specification 声明“空格字符被 `+' 替换,然后保留字符被转义,如 ([RFC1738 ])[w3.org/TR/html401/references.html#ref-RFC1738],第 2.2 节”。可能是您的服务器不关心并且 %20 有效,但它是错误的编码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 2015-03-31
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多