ios多部分图片上传,上传的文件已损坏

时间:2015-05-12 10:41:55

标签: ios http post image-uploading multipartform-data

我正在向服务器发出多部分POST请求,一切正常,但我上传的jpeg没有文件扩展名,无法打开(文件大小与原始文件大小相同)。我在不同的服务器上试过这个并且发生了同样的错误,所以我认为这是我的应用程序代码的问题。

let boundary = generateBoundaryString()
    let request = NSMutableURLRequest(URL: Urls.sendFileURL)
    request.HTTPMethod = "POST"
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    let body = NSMutableData()

    for (key, value) in params {
        body.appendString("--\(boundary)\r\n")
        body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
        body.appendString("\(value)\r\n")
    }


    let imageData: NSData = UIImageJPEGRepresentation(photo, 0.8)

    body.appendString("--\(boundary)\r\n")
    body.appendString("Content-Disposition: form-data; name=\"iosUpload\"; filename=\"iosUpload.jpg\"\r\n\r\n")
    body.appendString("Content-Type: image/jpeg\r\n\r\n")
    body.appendData(imageData)
    body.appendString("\r\n")
    body.appendString("--\(boundary)\r\n")

    request.HTTPBody = body

我已经使用posttestserver.com尝试了我的POST  this is the result

2 个答案:

答案 0 :(得分:1)

我遇到了类似的问题:我使用multipart/form-data上传了一个jpeg,当我从服务器重新下载相同的文件时,它不能由Preview.app打开,也不能它用于创建UIImage的实例,因为它已损坏。

enter image description here

我与FileMerge.app(包含在Xcode.app/Contents/Applications/中)并排打开了两个文件,令我惊讶的是,损坏的文件顶部有一个额外的空行(CRLF); 否则,它们是相同的

显然,我在之前插入额外的\r\n 我将文件的内容附加到上传请求的正文中。

我改变了我的上传代码:

let body = NSMutableData()

body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"inputFile\"; filename=\"\(fileName)\"\r\n")
body.appendString("Content-Type: image/jpeg\r\n\r\n\r\n") // !!!! THREE CRLF
body.appendData(fileData)    
body.appendString("\r\n--\(boundary)--")

......对此:

let body = NSMutableData()

body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"inputFile\"; filename=\"\(fileName)\"\r\n")
body.appendString("Content-Type: image/jpeg\r\n\r\n") // !!!! TWO CRLF
body.appendData(fileData)    
body.appendString("\r\n--\(boundary)--")

...现在下载的文件是一个有效的jpeg,与我上传的文件相同。

因此,我建议您并排打开两个版本的文件,然后查看更改内容。

(FileMerge会抱怨"文件不是ascii。",但只是忽略它并继续。)

答案 1 :(得分:0)

我不熟悉ios,但你找不到用于构建多部分请求的库,而你必须自己动手?

我至少可以发现以下问题:

1)

@property (nonatomic, strong) UIColor *lineColor;
//If you need to keep track of multiple overlays, 
//try using a NSMutableDictionary where the keys are the 
//overlay titles and the value is the UIColor.

-(void)methodWhereYouOriginallyCreateAndAddTheOverlay
{
    self.lineColor = [UIColor blueColor];  //line starts as blue
    MKPolyline *pl = [MKPolyline polylineWithCoordinates:coordinates count:count];
    pl.title = @"test";
    [mapView addOverlay:pl];
}

-(void)methodWhereYouWantToChangeLineColor
{
    self.lineColor = theNewColor;

    //Get reference to MKPolyline (example assumes you have ONE overlay)...
    MKPolyline *pl = [mapView.overlays objectAtIndex:0];

    //Get reference to polyline's renderer...
    MKPolylineRenderer *pr = (MKPolylineRenderer *)[mapView rendererForOverlay:pl];
    pr.strokeColor = self.lineColor;
    [pr invalidatePath];
}

-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
    if ([overlay isKindOfClass:[MKPolyline class]]) {
        MKPolylineRenderer *pr = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
        pr.strokeColor = self.lineColor;
        pr.lineWidth = 5;
        return pr;
    }

    return nil;
}

这里有额外的body.appendString("Content-Disposition: form-data; name=\"iosUpload\"; filename=\"iosUpload.jpg\"\r\n\r\n") 。它应该是

\r\n

2)

body.appendString("Content-Disposition: form-data; name=\"iosUpload\"; filename=\"iosUpload.jpg\"\r\n")

在此处缺少结尾body.appendString("--\(boundary)\r\n") 。它应该是

--