【问题标题】:Upload an sqlite file上传一个 sqlite 文件
【发布时间】:2014-12-24 14:21:31
【问题描述】:

我正在使用 AFNetworking 尝试上传文件:

-(void)uploadFile{

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"data.sqlite"];
    NSURL *filePathURL = [NSURL fileURLWithPath:filePath];

    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://localhost:8888/myApp/upload.php" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileURL:filePathURL name:@"file" fileName:@"data.sqlite" mimeType:@"text/html" error:nil];
    } error:nil];

    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    NSProgress *progress = nil;

    NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
        if (error) {
            NSLog(@"Error: %@", error);
        } else {
            NSLog(@"Success: %@ %@", response, responseObject);
        }
    }];

    [uploadTask resume];
}

还有这个php文件upload.php

<?php

    $uploaddir = 'uploads/';
    $file = basename($_FILES['uploadedfile']['name']);
    $uploadfile = $uploaddir . $file;

    echo "file=".$file;

    if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $uploadfile)) {
        echo $file;
    }
    else {
        echo "error";
    }
    ?>

正在打印:

错误域=com.alamofire.error.serialization.response Code=-1016 “请求失败:不可接受的内容类型:文本/html” 用户信息=0x7b8b2bf0

问题出在mimeType 吗?我还在 iOS 和 php 端都使用了 application/x-sqlite3 内容类型。

【问题讨论】:

  • 上传文件时需要有效的enctype。
  • 试试application/octet-stream,这是未知二进制流的备用mime类型。正如 RFC 2388 所说,“与所有多部分 MIME 类型一样,每个部分都有一个可选的‘Content-Type’,默认为 text/plain。如果文件的内容是通过填写表单返回的,那么文件输入是标识为适当的媒体类型(如果已知)或“应用程序/八位字节流”。”
  • 我还建议为multipartFormRequestWithMethod 提供一个error 参数。顺便说一句,请参阅我的更新回复responseSerializer
  • 你说“我还在 iOS 和 php 端都使用了application/x-sqlite3 内容类型。” “php 端”是什么意思? header() 电话?!? application/x-sqlite3 在那里不合适。有两个完全不同的Content-Type 设置。一种是客户端代码中多部分请求部分的 mime 类型(应该是 application/octet-streamapplication/x-sqlite3)。另一个是您的 PHP 代码中响应的标头(对于当前的 PHP 代码,它应该是 text/plain,或者如果您将 PHP 代码更改为返回 JSON,它应该是 application/json)。
  • @Rob:一个非常解释的 cmets,完美!所以客户端部分(iOS)正在发送一个 sqlite 文件,所以 mimeType 将是 application/octet-streamapplication/x-sqlite3,而对于服务器端,在我的情况下返回纯文本,所以 content-type 将是 text/plain

标签: php ios afnetworking-2


【解决方案1】:

客户端代码正在使用file 字段名称上传,但服务器代码正在寻找uploadedfile。您必须在两个平台上使用相同的字段名称。

mime 类型应该是固定的。因为 SQLite 文件是二进制文件,而不是文本文件,我建议使用 application/x-sqlite3application/octet-stream 的 mime 类型,而不是 text/htmltext/plain。但不匹配的字段名称是更严重的问题。


对了,你报错信息:

Error Domain=com.alamofire.error.serialization.response Code=-1016 "请求失败:不可接受的内容类型:text/html" UserInfo=0x7b8b2bf0

这通常是您的服务器页面返回 text/html,但 AFURLSessionManager 期待 JSON。

您可以更改经理的responseSerializer

manager.responseSerializer = [AFHTTPResponseSerializer serializer];

或者,更好的是,更改您的服务器代码以返回 JSON。

【讨论】:

  • “因为 SQLite 文件是二进制文件,而不是文本文件” - 啊,我直到现在才知道。我并不是想早先向 OP 提供有关将其更改为 text/plain 的错误信息,这是我的错误。我会记住那个的。
  • 非常感谢 Rob,您一直在这里帮助我们。我现在有一个success 回复,这完全是合乎逻辑的。谢谢并接受!
猜你喜欢
  • 2014-01-02
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-25
  • 2012-05-08
相关资源
最近更新 更多