【问题标题】:Objective C: How to upload image and text using HTTP POST?目标 C:如何使用 HTTP POST 上传图像和文本?
【发布时间】:2011-07-22 06:39:11
【问题描述】:

我已经成功创建了两种不同的方法,它们中的每一个都可以上传图像或文本。但是我在编写可以同时发布文本和图像的方法时遇到问题!

// 这是我的新方法,女巫比@sgosha 做得很好:

- (void) upload {
    NSString *urlString = @"http://www.examplescript.com";
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"POST"];

    NSMutableData *body = [NSMutableData data];


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

    // file
    NSData *imageData = UIImageJPEGRepresentation(imageView.image, 90);

    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"Content-Disposition: attachment; name=\"userfile\"; filename=\".jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:imageData]];
    [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

    // Text parameter1
    NSString *param1 = @"parameter text";
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"parameter1\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:param1] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

    // Another text parameter
    NSString *param2 = @"Parameter 2 text";
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"parameter2\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:param2] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

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

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

    //return and test
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

    NSLog(@"%@", returnString);
}

//老问题: 显然这太容易了,没有奏效!我在控制台或任何东西中都没有收到任何错误,并且图像已上传,但未发送文本。有什么想法吗?

顺便说一句:服务器端脚本是一个非常简单的 php 脚本。

【问题讨论】:

  • 或许你可以使用ASIHTTPRequest 轻松搞定。
  • 截至 2013 年 1 月 17 日,请查看 github 上的 AFNetworking 库。这是在 http 和 https 上上传多部分/表单数据的最佳方式。它使用块。编写干净漂亮的代码。
  • 可以分享php脚本吗?
  • 在这里找到答案 Uploading Text File to php server

标签: iphone objective-c ipad file-upload http-post


【解决方案1】:

此代码适用于我使用 POST 请求的 1 张图片和 7 个其他参数

确保更改您的变量名称加上值以及图像参数名称加上“showPhoto”,这是我的 IBOutlet UIImageView 对象 'name' 显示 URL 参数名称。

NSString *str=@"http://xxx.xxx.xxx.xx/xxxx/xxxxx/xxxxx.php?action=add_place"; NSString *urlString = [NSString stringWithFormat:@"%@",str];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[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"];

 NSData *imageData = UIImageJPEGRepresentation(_showPhoto.image, 90);

[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"host_pic\"; filename=\"parkN.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

//  parameter username

[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userID\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[@"17" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];


//  parameter token
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"longitude\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[@"50.0011" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

//  parameter token
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"latitude\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[@"50.0011" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

// parameter method
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"place_name\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[@"lahore" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];


//parameter method
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"place_description\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[@"lahore" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

//parameter method
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"zip_code\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[@"123456" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

//parameter method
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"phone_number\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[@"033333333" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];


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


// setting the body of the post to the reqeust
[request setHTTPBody:body];


NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"%@",dict);

【讨论】:

    【解决方案2】:

    我还想在同一个 POST 中上传一张图片和其他数据,关于上传图片的大部分信息只是在一个服务器连接中单独上传一张图片,这就是我解决这个问题的方法。

    这是PHP

    <?php
    /* As you can see there are more values not only the image */
    $variableOne    = $_POST['variableOne'];
    $variableTwo    = $_POST['variableTwo'];
    $variableThree  = $_POST['variableThree'];
    $variableFour   = $_POST['variableFour'];
    $variableFive   = $_POST['variableFive'];
    $variableSix    = $_POST['variableSix'];
    $variableSeven  = $_POST['variableSeven'];
    $variableEight  = $_POST['variableEight'];
    $variableNine   = $_POST['variableNine'];
    $variableTen    = $_POST['variableTen'];
    
    /* Our image */
    $image = $_REQUEST['image'];
    
    /* This is for trying to get a unique name for the image file, since maybe you want to store large amount of images */
    $currentDate = date("Y-m-d");
    $name  = "" . $currentDate . microtime() . rand(0, 999) . rand(0, 999) . rand(0, 999) . ".jpg";
    
    /* 
     * Here comes the image stuff
     */
    if (file_exists($name)) {
        echo "File already exists";
    } else {
            /* Decoding image */
            $binary = base64_decode($image);
    
            /* Opening image */
            $file = fopen($name, 'wb');
    
            /* Writing to server */
            fwrite($file, $binary);
    
            /* Closing image file */
            fclose($file);
    
            echo "Added";
        }   
    }   
    ?>
    

    然后在Xcode中复制粘贴这个方法(取自Creating a base-64 string from NSData

    - (NSString*)base64forData:(NSData*) theData {
        const uint8_t* input = (const uint8_t*)[theData bytes];
        NSInteger length = [theData length];
    
        static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    
        NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
        uint8_t* output = (uint8_t*)data.mutableBytes;
    
        NSInteger i;
        for (i=0; i < length; i += 3) {
            NSInteger value = 0;
            NSInteger j;
            for (j = i; j < (i + 3); j++) {
                value <<= 8;
    
                if (j < length) {
                    value |= (0xFF & input[j]);
                }
            }
    
            NSInteger theIndex = (i / 3) * 4;
            output[theIndex + 0] =                    table[(value >> 18) & 0x3F];
            output[theIndex + 1] =                    table[(value >> 12) & 0x3F];
            output[theIndex + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
            output[theIndex + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
        }
    
        return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    }
    

    在 YourViewController.h 文件中

    @interface YourViewController : UIViewController {
        NSURLConnection *serverConnection;
        NSMutableData *returnData;
    }
    

    这是服务器连接代码

    NSURL *sendURL = [NSURL URLWithString:@"http://yourdomainname/imagefolder/phpscript.php"];
    
    NSMutableURLRequest *sendRequest = [NSMutableURLRequest requestWithURL:sendURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
    
    [sendRequest setHTTPMethod:@"POST"];
    
    [sendRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    
    NSData *imageData = UIImageJPEGRepresentation(yourImage, 1.0);
    
    NSString *encodedString = [[self base64forData:imageData] stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];
    
    NSString *dataToSend = [[NSString alloc] initWithFormat:@"variableOne=%@&variableTwo=%@&variableThree=%@&variableFour=%@&variableFive=%@&variableSix=%@&variableSeven=%@&variableEight=%@&variableNine=%@&variableTen=%@&image=%@", valueOne, valueTwo, valueThree, valueFour, valueFive, valueSix, valueSeven, valueEight, valueNine, valueTen, encodedString];
    
    [sendRequest setHTTPBody:[dataToSend dataUsingEncoding:NSUTF8StringEncoding]];
    
    serverConnection = [[NSURLConnection alloc] initWithRequest:sendRequest delegate:self];
    
    [serverConnection start];
    

    设置服务器连接的委托方法

    - (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
        returnData = [[NSMutableData alloc] init];
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
        [returnData appendData:data];
    }
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
        if (connection == serverConnection) {
            NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
    
            NSLog(@"Response: %@", responseString);
    
            if ([responseString isEqualToString:@"Added"]) {
    
                /* Make something on success */
    
            } else {
    
                /* Make something else if not completed with success */
    
            }
        }
    }
    
    - (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    {
        /* Make something on failure */
    }
    

    【讨论】:

    • 很好的例子...完美运行。也感谢它的 PHP 方面!
    【解决方案3】:

    如果要给图片命名:

     NSMutableString *nombreImagen= [[NSMutableString alloc]init];
        [nombreImagen appendString:@"Content-Disposition: attachment; name=\"file\"; filename=\""];
        [nombreImagen appendString:@"hoy"];
        [nombreImagen appendString:@".jpg\"\r\n"];
        .......
    
       [body appendData:[[NSString stringWithString:nombreImagen] dataUsingEncoding:NSUTF8StringEncoding]];
    

    【讨论】:

      【解决方案4】:

      试试这个(已编辑):

      NSMutableData *body = [NSMutableData data];
      
      // file
      [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[[NSString stringWithString:@"Content-Disposition: attachment; name=\"userfile\"; filename=\".jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[NSData dataWithData:imageData]];
      [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
      
      // text parameter
      [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"parameter1\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[parameterValue1 dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
      
      // another text parameter
      [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"parameter2\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[parameterValue2 dataUsingEncoding:NSUTF8StringEncoding]];
      [body appendData:[[NSString stringWithString:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
      
      // close form
      [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
      
      // set request body
      [request setHTTPBody:body];

      【讨论】:

      • “附件”是您在这里完成的唯一编辑吗?如果是这样,我应该在哪里传递文本?这是否只是说明图像作为附件发送,然后我可以在边界之后但在 setHTTPBody 调用之前以代码形式发送文本?
      • Tnx,用于质量代码:D 现在工作得很好,将用我现在工作正常的方法更新原始帖子!
      • 感谢您。真的有帮助。完全停留在如何将文本参数与图像一起发送
      • 请考虑更新为使用Content-Disposition:form-data;charset=UTF-8;name=...,因为这将匹配编码NSUTF8StringEncoding。粘贴到表单创建的非英文字符对于发布此解决方案的服务器无法使用
      • 什么是边界?谁能解释一下?
      猜你喜欢
      • 2012-01-23
      • 1970-01-01
      • 2015-02-07
      • 2017-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多