Objective C 实现application/x-www-form-urlencoded类型提交

Objective C 2020-03-25 阅读 144 评论 0

application/x-www-form-urlencoded 是浏览器默认的编码格式,请求的数据被编码成以 '&' 分隔的键-值对,同时以 '=' 分隔键和值。这种类型不支持二进制数据(应使用 multipart/form-data 代替)。multipart/form-data的实现,可以参考 Objective C 实现 http post multipart/form-data 类型的请求

实现示例

HttpPostForm.h

#import <Foundation/Foundation.h>

@interface HttpPostForm:NSObject
-(id)initWithUrl:(NSString *)urlString;

@property(nonatomic) NSMutableURLRequest *request;
@property(nonatomic) NSString *urlString;
@property(nonatomic) NSMutableDictionary *headers;
@property(nonatomic) NSMutableDictionary *fields;

/// 添加请求头
/// @param key 请求头的名
/// @param value 请求头的值
-(void)addHeader:(NSString *)key value:(NSString *)value;

/// 添加参数字段
/// @param key 字段名称
/// @param value 值
-(void)addFormField:(NSString *)key value:(NSString *)value;

/// 完成请求
/// @param callback 回调块
- (void)finish:(void(^)(NSData *, NSURLResponse *, NSError *))callback;

@end

HttpPostForm.m

#import "HttpPostForm.h"

@implementation HttpPostForm

-(id)initWithUrl:(NSString *)urlString{
  self.request = [[NSMutableURLRequest alloc]init];
  self.urlString = urlString;
  self.headers = [[NSMutableDictionary alloc]init];
  self.fields = [[NSMutableDictionary alloc]init];
  return self;
}

-(void)addHeader:(NSString *)key value:(NSString *)value{
  [self.headers setObject:value forKey:key];
}

-(void)addFormField:(NSString *)key value:(NSString *)value{
  [self.fields setObject:value forKey:key];
}

- (void)finish:(void (^)(NSData *, NSURLResponse *, NSError *))callback{
  NSURL *url = [[NSURL alloc]initWithString:self.urlString];
  [self.request setURL:url];
  [self.request setHTTPMethod:@"POST"];
  // 添加请求头
  for (NSString *key in self.headers){
    NSString *value = self.headers[key];
    [self.request setValue:value forHTTPHeaderField:key];
  }
  // 添加请求头 Content-Type
  [self.request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
  // 添加请求参数
  NSMutableData *body = [NSMutableData data];
  for (NSString *key in self.fields){
    NSString *value = self.fields[key];
    [body appendData:[[NSString stringWithFormat:@"%@=%@", key, value] dataUsingEncoding:NSUTF8StringEncoding]];
  }
  
  if ([body length] > 0) {
    [self.request setHTTPBody:body];
    // 添加请求头 content-length
    NSString *postLength = [NSString stringWithFormat:@"%ld", [body length]];
    [self.request setValue:postLength forHTTPHeaderField:@"Content-Length"];
  }
  
  void (^completionHandler)(NSData *, NSURLResponse *, NSError *) = ^(NSData *data, NSURLResponse *response, NSError *error) {
    if (callback) {
      callback(data, response, error);
    }
  };
  
  [[[NSURLSession sharedSession] dataTaskWithRequest:self.request completionHandler:completionHandler] resume];
}

@end

调用示例

NSString *url = @"http://localhost";
HttpPostForm *request = [[HttpPostForm alloc]initWithUrl:url];
// 添加 user-agent
[request addHeader:@"User-Agent" value:@"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36"];
// 添加 请求参数
[request addFormField:@"username" value:@"test"];

void (^completionHandler)(NSData *, NSURLResponse *, NSError *) = ^(NSData *data, NSURLResponse *response, NSError *error) {
    if (data == nil || data.length == 0 || response == nil || [(NSHTTPURLResponse *)response statusCode] != 200) {
        NSLog(@"error");
        return;
    }
    NSLog(@"success: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
};
[request finish:completionHandler];
最后更新 2020-03-25