【问题标题】:POST jpeg upload with AFNetworking使用 AFNetworking POST jpeg 上传
【发布时间】:2023-04-03 16:35:01
【问题描述】:

我一辈子都想不通为什么当我使用 AFNetworking 时这不起作用。它与 ASIHTTP 一起工作。这对我来说都是很新鲜的。但我无法弄清楚为什么文件不再从 $_FILES 传输到服务器的 HD 了。这是 iOS 代码:

- (IBAction)uploadPressed 
{
[self.fileName resignFirstResponder];
NSURL *remoteUrl = [NSURL URLWithString:@"http://mysite.com"];

NSTimeInterval timeInterval = [NSDate timeIntervalSinceReferenceDate];
NSString *photoName=[NSString stringWithFormat:@"%lf-Photo.jpeg",timeInterval];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];

// the path to write file
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:photoName];
NSData * photoImageData = UIImageJPEGRepresentation(self.remoteImage.image, 1.0);
[photoImageData writeToFile:filePath atomically:YES];

NSLog(@"photo written to path: e%@", filePath);

AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:remoteUrl];
NSMutableURLRequest *afRequest = [httpClient multipartFormRequestWithMethod:@"POST" 
                                                                       path:@"/photos" 
                                                                 parameters:nil 
                                                  constructingBodyWithBlock:^(id <AFMultipartFormData>formData) 
                                  {
                                      [formData appendPartWithFormData:[self.fileName.text dataUsingEncoding:NSUTF8StringEncoding] 
                                                                  name:@"name"];


                                      [formData appendPartWithFileData:photoImageData 
                                                                  name:self.fileName.text 
                                                              fileName:filePath 
                                                              mimeType:@"image/jpeg"]; 
                                  }
                                  ];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest];
[operation setUploadProgressBlock:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {

    NSLog(@"Sent %d of %d bytes", totalBytesWritten, totalBytesExpectedToWrite);

}];

   [operation setCompletionBlock:^{
    NSLog(@"%@", operation.responseString); //Gives a very scary warning
}];

[operation start];    



}

我曾经这样做过:

ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:remoteUrl];
[request setPostValue:self.fileName.text forKey:@"name"];
[request setFile:filePath forKey:@"filename"];
[request setDelegate:self];
[request startAsynchronous];

这是我的 PHP:

 {
// these could be stored in a .ini file and loaded
// via parse_ini_file()... however, this will suffice
// for an example
$codes = Array(
    100 => 'Continue',
    101 => 'Switching Protocols',
    200 => 'OK',
    201 => 'Created',
    202 => 'Accepted',
    203 => 'Non-Authoritative Information',
    204 => 'No Content',
    205 => 'Reset Content',
    206 => 'Partial Content',
    300 => 'Multiple Choices',
    301 => 'Moved Permanently',
    302 => 'Found',
    303 => 'See Other',
    304 => 'Not Modified',
    305 => 'Use Proxy',
    306 => '(Unused)',
    307 => 'Temporary Redirect',
    400 => 'Bad Request',
    401 => 'Unauthorized',
    402 => 'Payment Required',
    403 => 'Forbidden',
    404 => 'Not Found',
    405 => 'Method Not Allowed',
    406 => 'Not Acceptable',
    407 => 'Proxy Authentication Required',
    408 => 'Request Timeout',
    409 => 'Conflict',
    410 => 'Gone',
    411 => 'Length Required',
    412 => 'Precondition Failed',
    413 => 'Request Entity Too Large',
    414 => 'Request-URI Too Long',
    415 => 'Unsupported Media Type',
    416 => 'Requested Range Not Satisfiable',
    417 => 'Expectation Failed',
    500 => 'Internal Server Error',
    501 => 'Not Implemented',
    502 => 'Bad Gateway',
    503 => 'Service Unavailable',
    504 => 'Gateway Timeout',
    505 => 'HTTP Version Not Supported'
);

return (isset($codes[$status])) ? $codes[$status] : '';
}

function sendResponse($status = 200, $body = '', $content_type = 'text/html')
{
$status_header = 'HTTP/1.1 ' . $status . ' ' . getStatusCodeMessage($status);
header($status_header);
header('Content-type: ' . $content_type);
echo $body;
}

if (!empty($_FILES) && isset($_POST["name"])) {
            $name = $_POST["name"];
            $tmp_name = $_FILES['filename']['tmp_name'];
            $uploads_dir = '/var/www/cnet/photos';
            move_uploaded_file($tmp_name, "$uploads_dir/$name.jpg");
            $result = array("SUCCEEDED");
            sendResponse(200, json_encode($result));
            } else {

            sendResponse(400, 'Nope');
            }
?>

【问题讨论】:

  • 一些 cmets:你应该使用 !empty($_FILES) 而不是 isset($_FILES) & $_FILES['filename']['tmp_name'] 将返回上传文件的完整路径,因此 move_uploaded_file 将不起作用,如果您将 error_reporting(E_ALL) 添加到你的 php 文件的顶部然后你会看到错误...
  • 谢谢!我继续将 isset 更改为 !empty。并打开error_reporting。但这是从我的 iPhone 到服务器的。我不知道我应该在哪里看到错误。关于 move_uploaded_files 语法,我直接从 php 手册 php.net/manual/en/function.move-uploaded-file.php 中提取。
  • 我修复了 php 代码并使用我的应用程序的旧 ASIHTTPFormRequest 版本运行它。它仍然这样工作。问题肯定出在这里的 AFNetworking 实现中。

标签: php iphone objective-c http afnetworking


【解决方案1】:

试试这个sn-p的代码:

    NSData* sendData = [self.fileName.text dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *sendDictionary = [NSDictionary dictionaryWithObject:sendData forKey:@"name"];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:remoteUrl];
    NSMutableURLRequest *afRequest = [httpClient multipartFormRequestWithMethod:@"POST" 
                                                                           path:@"/photos" 
                                                                     parameters:sendDictionary 
                                                      constructingBodyWithBlock:^(id <AFMultipartFormData>formData) 
                                      {                                     
                                          [formData appendPartWithFileData:photoImageData 
                                                                      name:self.fileName.text 
                                                                  fileName:filePath 
                                                                  mimeType:@"image/jpeg"]; 
                                      }
                                      ];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:afRequest];
    [operation setUploadProgressBlock:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {

        NSLog(@"Sent %d of %d bytes", totalBytesWritten, totalBytesExpectedToWrite);

    }];

    [operation setCompletionBlock:^{
        NSLog(@"%@", operation.responseString); //Gives a very scary warning
    }];

    [operation start]; 

【讨论】:

  • 但是如果有什么方法可以在没有警告的情况下使用它呢?
【解决方案2】:

我不太熟悉 ASI 对 setPostValue:forKey: 所做的事情,但您可能缺少与图片上传分开发送的 name 参数。

客户端或服务器究竟记录了什么?进度块记录了吗?

其他几点:

  • 你可以在最后做[operation start];无需为此创建操作队列。
  • 为了帮助进行日志记录,请将 completionBlock 设置为 operation,并在响应中添加 NSLog 或类似内容。
  • 您可能希望使用类方法创建一个AFHTTPClient 基类以返回单例实例,例如AFNetworking 示例应用程序中的Gowalla API 客户端。然后,该客户端可以为您的所有网络请求管理一个操作队列。

【讨论】:

  • 我将上面的代码调整为最新的。验证 PHP 工作正常。我正在尝试执行完成块,但它不会让我记录 operation.responsString。我应该在块中放什么?
  • 唉!我让完成块开始工作。它给了我“不”,这意味着他们至少在相互交流。但我收到了 400 条回复。所以代码说 $_FILES 是空的或者 $_POST['name'] 没有设置。我还添加了@"name" appendPartWithFormData。您可以首先看到两者中最新的。所以这个表单数据还没有被正确发送。
  • 更新到2.0后,没有AFHTTPClient,使用Igor Fedorchuk的代码得到警告,还有新的api吗?
【解决方案3】:

我有一个使用 NSMutableURLRequest 的解决方法:

NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:remoteUrl];
[req setHTTPMethod:@"POST"];

NSString *contentType = [NSString stringWithFormat:@"multipart/form-data, boundary=%@", boundary];
[req setValue:contentType forHTTPHeaderField:@"Content-type"];

//adding the body:
NSMutableData *postBody = [NSMutableData data];
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[@"Content-Disposition: form-data; name=\"name\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[name dataUsingEncoding:NSUTF8StringEncoding]];

[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[@"Content-Disposition: form-data; name=\"filename\";\r\nfilename=\"china.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[NSData dataWithData:imageData]];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[req setHTTPBody:postBody];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 2013-11-19
    • 1970-01-01
    相关资源
    最近更新 更多