iOS 用HTTP post上传图片到OSS

本文分享了一位开发者使用阿里云OSS手动上传图片的经历,包括如何构建HTTP POST请求及必要的表单数据,并提供了详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

唉!都是泪啊 。用惯了AFNetWorking的我这次是被坑了。这次老大非要求使用http自己写上传图片到OSS,搞了两天才搞好,头都大了。应该以后

  1. Content-Type: multipart/form-data; boundary=9431149156168
的关于这种的我都会这样写,记录一下。

首先关于post:这儿给个表单,详情点post要求

Post object

请求语法

 
  1. POST / HTTP/1.1
  2. Host: BucketName.oss-cn-hangzhou.aliyuncs.com
  3. User-Agent: browser_data
  4. Content-LengthContentLength
  5. Content-Type: multipart/form-data; boundary=9431149156168
  6. --9431149156168
  7. Content-Disposition: form-data; name="key"
  8. key
  9. --9431149156168
  10. Content-Disposition: form-data; name="success_action_redirect"
  11. success_redirect
  12. --9431149156168
  13. Content-Disposition: form-data; name="Content-Disposition"
  14. attachment;filename=oss_download.jpg
  15. --9431149156168
  16. Content-Disposition: form-data; name="x-oss-meta-uuid"
  17. myuuid
  18. --9431149156168
  19. Content-Disposition: form-data; name="x-oss-meta-tag"
  20. mytag
  21. --9431149156168
  22. Content-Disposition: form-data; name="OSSAccessKeyId"
  23. access-key-id
  24. --9431149156168
  25. Content-Disposition: form-data; name="policy"
  26. encoded_policy
  27. --9431149156168
  28. Content-Disposition: form-data; name="Signature"
  29. signature
  30. --9431149156168
  31. Content-Disposition: form-data; name="file"; filename="MyFilename.jpg"
  32. Content-Type: image/jpeg
  33. file_content
  34. --9431149156168
  35. Content-Disposition: form-data; name="submit"
  36. Upload to OSS
  37. --9431149156168--
之前接触这种东西太少了。


转到正题,上代码。

/从后台拿到oss_access_key_id,urlstr,policy,signature
- (void)getAccessTokenFromOSS{
    MySessionManager *manager = [MySessionManager manager];
    NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
    AppDelegate * appdegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    [dic setValue:appdegate.access_token        forKey:@"access_token"];
    [dic setValue:@"6000" forKey:@"duration"];
    NSString *url = [NSString stringWithFormat:@"%@/oss_access_token",URL_FACE];
    [manager POST:url parameters:dic success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        FaceModel *model = [RMMapper objectWithClass:[FaceModel class] fromDictionary:responseObject ];
        [self postOSSImageKeybucketName:model.oss_access_key_id url:model.url policy:model.policy Signature:model.signature];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
    }];
}

#pragma mark--NSURLConnection
- (void)postOSSImageKeybucketName:(NSString *)oss_access_key_id url:(NSString *)urlstr policy:(NSString *)policy Signature:(NSString *)signature{

    if (_currentImg == nil || !_currentImg) {
        return;
    }
    //2. 图片名字
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString * loginMobile = (NSString *) [defaults objectForKey:LOGIN_USERNAME];
    NSString *fileName = [NSString stringWithFormat:@"%@_%@.jpg",loginMobile,[ShareMethod currentTimeStr]];
    //3. 图片二进制文件
    NSData *imagedata = UIImageJPEGRepresentation(_currentImg, 0.00001);
    //4. 发起网络请求
    NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
    [dic setValue:oss_access_key_id forKey:@"OSSAccessKeyId"];
    [dic setValue:policy            forKey:@"policy"];
    [dic setValue:signature         forKey:@"Signature"];
    [dic setValue:fileName          forKey:@"key"];
    [dic setValue:imagedata         forKey:@"file"];
    [self networkWithURL:urlstr pic:_currentImg parameter:dic fileName:fileName success:^(id obj) {
        NSLog(@"成功");
    } fail:^(NSError *error) {
        NSLog(@"失败");
    }];
}

//图片以及其他信息上传
- (void)networkWithURL:(NSString *)url pic:(UIImage *)image parameter:(NSDictionary *)paraDic fileName:(NSString *)fileName success:(void (^)(id obj))success fail:(void (^)(NSError *error))fail {
    //分界线的标识符
    NSString *TWITTERFON_FORM_BOUNDARY = @"9431149156168";
    //根据url初始化request
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
                                                            cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                        timeoutInterval:10];
    //分界线 --AaB03x
    NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
    //结束符 AaB03x--
    NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
    //得到图片的data
    NSData *imagedata = UIImageJPEGRepresentation(image, 0.00001);
    //http body的字符串
    NSMutableString *body=[[NSMutableString alloc]init];
    //参数的集合的所有key的集合
    NSArray *keys= [paraDic allKeys];
    //遍历keys
    for(int i=0;i<[keys count];i++)
    {
        //得到当前key
        NSString *key=[keys objectAtIndex:i];
        //如果key不是pic,说明value是字符类型,比如name:Boris
        if (![key isEqualToString:@"file"]) {
            //添加分界线,换行
            [body appendFormat:@"%@\r\n",MPboundary];
            //添加字段名称,换2行
            [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
            //添加字段的值
            [body appendFormat:@"%@\r\n",[paraDic objectForKey:key]];
        }
        
    }
    ////添加分界线,换行
    [body appendFormat:@"%@\r\n",MPboundary];
    //声明pic字段,文件名为boris.png
    [body appendFormat:@"%@", [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@.jpg\"\r\n",fileName]];
    //声明上传文件的格式
    [body appendFormat:@"Content-Type: image/jpeg\r\n\r\n"];
    
    //声明结束符:--AaB03x--
    NSString *end=[[NSString alloc]initWithFormat:@"\r\n%@",endMPboundary];
    //声明myRequestData,用来放入http body
    NSMutableData *myRequestData=[NSMutableData data];
    //将body字符串转化为UTF8格式的二进制
    [myRequestData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
    //将image的data加入
    [myRequestData appendData:imagedata];
    //加入结束符--AaB03x--
    [myRequestData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
    
    //设置HTTPHeader中Content-Type的值
    NSString *content = [[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
    //设置HTTPHeader
    [request setValue:content forHTTPHeaderField:@"Content-Type"];
    //设置Content-Length
    [request setValue:[NSString stringWithFormat:@"%d", (int)[myRequestData length]] forHTTPHeaderField:@"Content-Length"];
    //设置http body
    [request setHTTPBody:myRequestData];
    //http method
    [request setHTTPMethod:@"POST"];
    //连接(NSURLSession)
    NSURLSession *session=[NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            NSLog(@"error:%@",error);
            NSLog(@"body%@",response);
            NSLog(@"response:%@",response);
            
        } else {
            NSLog(@"response:%@",response);
        }
        NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"body:%@", str);
        
    }];
    [dataTask resume];
    
}

欢迎有好方法的朋友补上代码,真的不容易啊,折腾!!

附上参考链接:http://www.superqq.com/blog/2014/12/11/nsmutableurlrequesthe-nsurlconnectionyong-postfang-shi-shang-chuan-zhao-pian/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值