【问题标题】:How to send muti-part form data with image and file, from ios to php server?如何将带有图像和文件的多部分表单数据从 ios 发送到 php 服务器?
【发布时间】:2023-04-04 23:30:02
【问题描述】:

我尝试将表单数据(带有图像和文件上传)从 ios 发送到 php 服务器,但所有尝试均失败。调试后发现:

  • 当我只发送表单数据和图像时,它工作正常。但是当我包含文件上传(在本例中为 mp3 文件)时,它失败了。表单数据和图片文件甚至没有传递到php端。
  • 如果我不包含mp3文件,服务器端将获取表单数据和图像文件。
  • 如果我只发送 mp3 文件,它不起作用。

这是我的ios代码:

//beginning data
NSDictionary *dictSong;
NSArray *arrImages; // Array of UIImage
NSArray *arrFiles; // Array of local file names to be sent to the server

// Build the request body
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:link]];
[request setHTTPMethod:@"POST"];

NSMutableData *body = [NSMutableData data];

NSString *boundary = @"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request addValue:contentType forHTTPHeaderField:@"Content-Type"];

// add the text form fields
if([dictData count] > 0) {
    for (id key in dictData) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithString:[dictData valueForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }
}
// add the image form fields
if ([arrImages count] > 0) {
    for(id key in arrImages) {
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: attachment; name=\"picture\"; filename=\"image.png\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[@"Content-Type: image/png\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[NSData dataWithData:UIImageJPEGRepresentation(key, 1.0)]];
        //[body appendData:[NSData dataWithData:key]];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }
}
// add the file form fields
if ([arrFiles count] != 0) {
    for(id key in arrFiles) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *docsDir = [paths objectAtIndex:0];
        NSString *dataPath = docsDir;
        if(folder)
            dataPath = [docsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@",folder]];
        NSString *fullPath = [dataPath stringByAppendingFormat:@"/%@", key];
        NSLog(@"fullPath: %@", fullPath); // file path has also been checked

        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: attachment; name=\"file\"; filename=\"file.mp3\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
        //[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; // I tried this line and the following line, but still failed
        [body appendData:[@"Content-Type: audio/mp3\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[NSData dataWithContentsOfFile:fullPath]];
        [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
    }
}

// close the form
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

// set request body
[request setHTTPBody:body];

然后我通过 NSURLSESSION 发送请求:

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration];

NSURLSessionDataTask *uploadTask = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { //Treat the response
}];

在服务器端,我检查:

echo $_POST["username"];
echo $_POST["password"];

$_FILES["picture"]["size"]

如果我在表单提交中包含 arrFiles,它们为零,否则正确数据。我做错了什么?

【问题讨论】:

  • 似乎我无法同时触发数据任务或上传表单数据和大文件的任务。所以我选择了一种方式,先发送表单数据和图像文件(使用数据任务),然后根据返回的数据发送歌曲文件(使用上传任务)。它不是很优雅,但至少它在头痛大约 2 周后奏效了。

标签: php ios forms post file-upload


【解决方案1】:

我没有成功地在文件上传的同时发送表单数据。所以解决方法是:

  1. 我在数据任务中将表单数据与图像文件一起发布到服务器;
  2. 在数据库中插入数据后,我指示服务器将新插入的item的id返回给app;
  3. 我通过上传任务将歌曲文件上传到服务器,使用上面第 2 点中收到的 id。

干杯!对于那些可能有更好解决方案的人,请分享。谢谢。

【讨论】:

    猜你喜欢
    • 2013-03-22
    • 2021-09-07
    • 2017-09-06
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多