POST请求上传多张图片并携带参数

简介:

POST请求上传多张图片并携带参数

在iOS中,用POST请求携带参数上传图片是非常恶心的事情,HTTPBody部分完全需要我们自己来配置,这个HTTPBody分为3个部分,头部分可以携带参数,中间部分就是我们要传输的图片文件,尾部就是结束标识了,这些设置完了还不够,你还需要配置一下HTTPHeaderField中的Content-Length以及Content-Type,恐怕一般人都会头大:).

完整的HTTPBody解密出来后是下面的格式:

--AaB03x
Content-Disposition: form-data; name="appkey"

peixunduoduo
--AaB03x
Content-Disposition: form-data; name="content"

真心太好用了!
--AaB03x
Content-Disposition: form-data; name="userid"
--AaB03x
Content-Disposition: form-data; name="sumscore"
--AaB03x
Content-Disposition: form-data; name="courseid"
--AaB03x
Content-Disposition: form-data; name="fromapp"
--AaB03x
Content-Disposition: form-data; name="sign"

003a0d94aff1c7728ab21eb785fbd544
--AaB03x
Content-Disposition: form-data; name="timestamp"


--AaB03x
Content-Disposition: form-data; name="image1"; filename="1.png"
Content-Type: image/png


<89504e47 0d0a1a0a 0000000d 49484452 000000c9 000000b9 08060000 0082e41b c4000000 1c69444f 54000000 02000000 00000000 5d000000 28000000 5d000000 5c000030 914514f9 44000030 5d494441 547801ec 7d0b7015 55ba2eea 8ce7a8e3 191d9ff8 0221ec50 35a335b7 4a92ec47 928d2373 4818e7e8 301254d4 0113f50e 09e21c08 1ec34b04 026a8023 210e11a3 189084b9 046a02c5 4b86644c 8e922a42 098c12ca 70490e82 6e2f8178 cd78bb4b 27c7f7fb 0d924e76 26c49c01 ecfdd078 fa059f2f fe098124 c4385d62 1c5f0c75 2dde0f81 e42a8384 8db86b91 b1aea53e 85401202 4908a401 78200492 0003d4d3 12d1a949 44a83850 ba00f69b ed439299 be63b7a7 db792dd1 e7310e14 b2d7fbfb ff017ed5 ee545a48 12fc0000 00004945 4e44ae42 6082>


--AaB03x--

本人封装好了上传图片的类,源码如下:

NETWorkPicUpload.h


//
//  NETWorkPicUpload.h
//  UploadPics
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import <Foundation/Foundation.h>

// 创建pictures数组需要的数据
NSData * createPNGPicture(NSString *formBoundary, UIImage *image,
                          NSString *name,         NSString *filename);

@interface NETWorkPicUpload : NSObject

@property (nonatomic, strong) NSString       *boundary;    // 分割字符串
@property (nonatomic, strong) NSDictionary   *parameters;  // 携带的参数
@property (nonatomic, strong) NSArray        *pictures;    // 封装好的图片的数据

- (void)configRequest:(NSMutableURLRequest **)request;

@end

NETWorkPicUpload.m


//
//  NETWorkPicUpload.m
//  UploadPics
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "NETWorkPicUpload.h"

@implementation NETWorkPicUpload

#pragma mark - 创建图片POST头部信息
- (NSData *)createParametersData
{
    // 生成了头部信息
    NSString        *start = [NSString stringWithFormat:@"--%@", _boundary];
    NSMutableString *body  = [[NSMutableString alloc] init];
    NSArray         *keys  = [_parameters allKeys];
    
    [keys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSString *key = keys[idx];
        
        [body appendFormat:@"\r\n%@\r\n", start];
        [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];
        [body appendFormat:@"%@",_parameters[key]];
    }];
    
    return [body dataUsingEncoding:NSUTF8StringEncoding];
}

#pragma mark - 创建图片POST尾部信息
- (NSData *)createEndData
{
    NSString *end = [NSString stringWithFormat:@"\r\n--%@--\r\n", _boundary];
    return [end dataUsingEncoding:NSUTF8StringEncoding];
}

#pragma mark - 生成POST需要的数据格式
- (NSData *)createPostData
{
    if (_boundary && _parameters)
    {
        NSMutableData *postData = [NSMutableData data];
        
        // 添加头
        [postData appendData:[self createParametersData]];
        
        // 添加图片
        [_pictures enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            if ([obj isKindOfClass:[NSData class]])
            {
                [postData appendData:obj];
            }
        }];
        
        // 添加尾
        [postData appendData:[self createEndData]];
        
        return postData;
    }
    else
    {
        return nil;
    }
}

#pragma mark - 创建PNG格式的图片
NSData * createPNGPicture(NSString *formBoundary, UIImage *image,
                          NSString *name,         NSString *filename)
{
    NSString *start = [NSString stringWithFormat:@"--%@", formBoundary];
    
    // 添加分界线,换行
    NSMutableString *subBody = [[NSMutableString alloc] init];
    [subBody appendFormat:@"\r\n%@\r\n", start];
    [subBody appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",
     name, filename];
    
    // 声明上传文件的格式
    [subBody appendFormat:@"Content-Type: image/png\r\n\r\n"];
    
    // 图片data
    NSData *imageData = UIImagePNGRepresentation(image);
    
    // 生成图片data
    NSMutableData *tmpData = [NSMutableData data];
    [tmpData appendData:[subBody dataUsingEncoding:NSUTF8StringEncoding]];
    [tmpData appendData:imageData];
    
    return [NSData dataWithData:tmpData];
}

- (void)configRequest:(NSMutableURLRequest **)request
{
    // 获取到了POST包体
    NSData *data = [self createPostData];
    
    // 配置请求
    NSMutableURLRequest *tmpRequest = *request;
    
    // 设置请求POST包体
    tmpRequest.HTTPBody    = data;
    tmpRequest.HTTPMethod  = @"POST";
    
    // 设置HTTPHeaderField
    [tmpRequest setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[data length]]
      forHTTPHeaderField:@"Content-Length"];
    [tmpRequest setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", _boundary]
      forHTTPHeaderField:@"Content-Type"];
}

@end

使用情况:

上传图片的截图:

说一下几个注意的地方:

以下地方会对request进行一些修改,注意**,这个是指针的指针,你懂得:)

 

大体流程就是:

1. 根据参数创建POST头部信息

2. 填充中间的图片信息

3. 用标示符表示结束信息

4. 对HTTPHeaderField进行一些设置

 

要实现以上这些是需要你对网络知识有着充分理解的:),也许你用惯了第三方开源代码,但不理解原理,还是很难根据需求进行必要修改,这一点需要注意哦.




目录
相关文章
|
SQL 人工智能 算法
Android性能优化之应用瘦身(APK瘦身)
Android性能优化之应用瘦身(APK瘦身)
|
2月前
|
人工智能 安全 JavaScript
喂饭级图文教程!阿里云部署OpenClaw+免费API配置+必装Skills清单及常见问题解答
熬夜部署完OpenClaw,满心期待迎来全能AI管家,结果发现它只会聊天——查股票不行、刷小红书不行、盯邮件也不行。这不是模型的问题,而是没给它装“技能包”(Skills)。正如参考文章所言,OpenClaw本体像刚买的智能手机,Skills就是让它“开窍”的App,装对了才能真正替你干活。
2003 4
|
NoSQL Linux MongoDB
CentOS 7.6安装 MongoDB 5.0.2
CentOS 7.6安装 MongoDB 5.0.2
2429 0
CentOS 7.6安装 MongoDB 5.0.2
|
移动开发 小程序 JavaScript
开源的微信小程序框架
【8月更文挑战第22天】开源的微信小程序框架
1188 65
|
存储 缓存 JSON
详解HTTP四种请求:POST、GET、DELETE、PUT
【4月更文挑战第3天】
75431 5
详解HTTP四种请求:POST、GET、DELETE、PUT
|
XML 存储 API
RAG效果优化:高质量文档解析详解
本文介绍了如何通过高质量的文档解析提升RAG系统整体的效果。
17279 15
|
消息中间件 NoSQL Redis
【赵渝强老师】Redis的消息发布与订阅
本文介绍了Redis实现消息队列的两种场景:发布者订阅者模式和生产者消费者模式。其中,发布者订阅者模式通过channel频道进行解耦,订阅者监听特定channel的消息,当发布者向该channel发送消息时,所有订阅者都能接收到消息。文章还提供了相关操作命令及示例代码,展示了如何使用Redis实现消息的发布与订阅。
471 0
|
存储 负载均衡 NoSQL
搭建高可用及负载均衡的Redis
通过本文介绍的高可用及负载均衡Redis架构,可以有效提升Redis服务的可靠性和性能。主从复制、哨兵模式、Redis集群以及负载均衡技术的结合,使得Redis系统在应对高并发和数据一致性方面表现出色。这些配置和技术不仅适用于小型应用,也能够支持大规模企业级应用的需求。希望本文能够为您的Redis部署提供实用指导和参考。
923 9
|
JSON 数据可视化 NoSQL
基于LLM Graph Transformer的知识图谱构建技术研究:LangChain框架下转换机制实践
本文介绍了LangChain的LLM Graph Transformer框架,探讨了文本到图谱转换的双模式实现机制。基于工具的模式利用结构化输出和函数调用,简化了提示工程并支持属性提取;基于提示的模式则为不支持工具调用的模型提供了备选方案。通过精确定义图谱模式(包括节点类型、关系类型及其约束),显著提升了提取结果的一致性和可靠性。LLM Graph Transformer为非结构化数据的结构化表示提供了可靠的技术方案,支持RAG应用和复杂查询处理。
1385 2
基于LLM Graph Transformer的知识图谱构建技术研究:LangChain框架下转换机制实践