iOS NSURLRequest POST request


iOS NSURLRequest POST request

我正试图使用下面的代码发送一个POST请求,其中包含一个音频文件和一些其他数据。服务器是用PHP编码的,尽管发送了请求并联系了服务器,但似乎没有可用的POST数据。下面的代码只需获取一个音频文件和另外两个名为cubeidrequest_type的字符串,并将它们作为POST变量发送

    // Create the request.
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@smartcube.php",[SMCGlobal apiURL]]]];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    // Create url connection and fire request
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    NSMutableData *body = [NSMutableData data];

    NSString *boundary = @"---------------------------14737809831466499882746641449";
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    [request addValue:contentType forHTTPHeaderField:@"Content-Type"];
    // file
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:@"track.m4a"];
    NSURL* soundURL = [NSURL URLWithString:plistPath];
    NSData *soundData = [NSData dataWithContentsOfURL:soundURL];
    [body appendData:[[NSString stringWithFormat:@"--%@'r'n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Disposition: form-data; name='"file'"; filename='"track.m4a'"'r'n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: audio/m4a'r'n'r'n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:soundData]];
    [body appendData:[@"'r'n" dataUsingEncoding:NSUTF8StringEncoding]];
    // Text parameter1
    NSDictionary* dic = [SMCGlobal returnUser];
    NSString *param1 = @"dhshahds";
    [body appendData:[[NSString stringWithFormat:@"--%@'r'n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name='"cubeid'"'r'n'r'n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:param1] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"'r'n" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"--%@'r'n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name='"request_type'"'r'n'r'n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"sendSpeech"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"'r'n" dataUsingEncoding:NSUTF8StringEncoding]];

    // close form
    [body appendData:[[NSString stringWithFormat:@"--%@--'r'n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    // set request body
    [request setHTTPBody:body];
    //return and test
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse* response, NSData* data, NSError *connectionError){
        NSLog(@"hehe");
        NSString* newStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if(connectionError){
            NSLog([connectionError localizedDescription]);
        }else{
            NSError *error;
            NSDictionary* dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
            if(error){
                NSLog([error localizedDescription]);
            }
            NSLog(@"haha");
        }
    }];

当我尝试在服务器上error_log(json_encode($_POST))时,它会返回一个空字符串。

几个观察结果:

  1. 这段代码发送两个请求,一个是XML请求(没有XML主体;lol),另一个是多部分请求。然后继续对原始请求进行变异,以便在第二个请求中使用。这似乎不可能是正确的。

    我认为您应该取消application/xml线路的Content-Type,以及conn连接的启动。

  2. 我建议不要使用边界,它本身有一堆前导连字符。这不是问题,但如果你在Charles这样的工具中观察原始请求,就会很难解释,因为哪些连字符是多部分分隔符语法的一部分,哪些是边界的一部分并不明显。

    就我个人而言,我会使用[[NSUUID UUID] UUIDString]作为我的边界。

  3. 正如韦恩所建议的那样,我会在查尔斯身上检查一下,看看请求在那里是否合理。