iOS Objective-C使用AFNetworking下载.xlsx文件遇content-type错误求助
解决iOS Objective-C中下载.xlsx文件时的Content-Type错误问题
我来帮你搞定这个问题!你碰到的unacceptable content-type: application/zip错误,本质是AFNetworking默认的可接受响应类型集合里没有包含application/zip,再加上你不想在SDK中依赖第三方库,这里给你两个实用方案:
方案一:调整AFNetworking的可接受内容类型(如果你仍想使用AFNetworking)
如果只是暂时需要兼容服务器返回的这个Content-Type,可以直接给AFNetworking的响应序列化器添加application/zip类型:
// 初始化会话管理器 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; // 获取原有可接受类型集合,添加新的Content-Type NSMutableSet *acceptableTypes = [NSMutableSet setWithSet:manager.responseSerializer.acceptableContentTypes]; [acceptableTypes addObject:@"application/zip"]; manager.responseSerializer.acceptableContentTypes = acceptableTypes; // 发起下载请求 [manager GET:@"你的文件下载URL" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { // 把返回的NSData写入本地文件 NSData *fileData = responseObject; NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *savePath = [docsPath stringByAppendingPathComponent:@"target.xlsx"]; if ([fileData writeToFile:savePath atomically:YES]) { NSLog(@"文件下载保存成功!"); } else { NSLog(@"文件写入失败"); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"下载出错:%@", error.localizedDescription); }];
注意:如果服务器返回的其实是zip压缩包(而非直接的xlsx文件),你还需要额外做解压操作;如果是服务器配置错误把xlsx的MIME类型标成了zip,直接保存成xlsx文件即可。
方案二:用原生NSURLSession实现下载(无第三方依赖,适合SDK集成)
既然你不想在SDK里引入第三方库,原生的NSURLSession是最佳选择——它完全不需要依赖任何外部框架,也不会有Content-Type的校验限制:
NSURL *downloadURL = [NSURL URLWithString:@"你的文件下载URL"]; NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL]; // 创建下载任务 NSURLSessionDownloadTask *downloadTask = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable tempLocation, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { NSLog(@"下载失败:%@", error.localizedDescription); return; } // 把临时文件移动到持久化目录(临时文件会被系统自动清理) NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; // 可以从响应头获取建议的文件名,或者自定义 NSString *fileName = response.suggestedFilename ?: @"downloaded.xlsx"; NSString *savePath = [docsPath stringByAppendingPathComponent:fileName]; NSFileManager *fileManager = [NSFileManager defaultManager]; // 先删除已存在的同名文件 if ([fileManager fileExistsAtPath:savePath]) { [fileManager removeItemAtPath:savePath error:nil]; } // 移动临时文件到目标路径 NSError *moveError; BOOL isSuccess = [fileManager moveItemAtURL:tempLocation toURL:[NSURL fileURLWithPath:savePath] error:&moveError]; if (isSuccess) { NSLog(@"文件下载完成,保存路径:%@", savePath); } else { NSLog(@"移动文件失败:%@", moveError.localizedDescription); } }]; // 启动下载任务 [downloadTask resume];
这种方式不仅避免了第三方依赖,还能绕开Content-Type的校验问题,非常适合SDK这类对依赖严格的场景。
另外提个小建议:如果可以的话,最好和后端同学沟通,把xlsx文件的响应Content-Type改成标准的application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,这样不管用哪种方式下载都不会有类型校验的问题。
内容的提问来源于stack exchange,提问作者Priyanka Wadher Mistry
相关产品推荐
相关产品推荐

