从iOS发送POST参数的问题

时间:2014-03-16 08:58:41

标签: ios iphone objective-c nsurlconnection nsurlrequest

我想在POST参数中发送imageUrl,该参数可以有&。 imageUrl可以是http://www.url.com?param1=edfef&param2=erfregreg

现在,如果我将此信息直接发送到服务器,则&之后不会考虑任何参数。关于SO的其他答案建议将&替换为%26。但这不起作用。因为当我转义整个POST参数字符串时,它将用%替换%26中的%25。即。http://www.url.com?param1=edfef%2526param2=erfregreg使网址无效。

逃脱params的代码:

NSMutableString *postParams = [NSMutableString stringWithFormat:@"imageUrl=%@&realName=%@, imageUrl, realName];
NSMutableString *escapeParams = (NSMutableString*)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,  (CFStringRef)postParams, NULL,(CFStringRef)@" !%?$#[]/+:@;*()'\"",kCFStringEncodingUTF8));   
self.postParameters = escapeParams;

更新:我尝试了下面的代码,但没有工作。

// URL
NSString * url = [NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?width=250&height=250", fbId];

NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (__bridge CFStringRef) url,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8));

url = escapedString;

// Making REST API call to store user details in table.
NSMutableString *postParams = [NSMutableString stringWithFormat:@"imageUrl=%@&realName=%@", imageUrl, realName];
NSMutableString *escapeParams = (NSMutableString*)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,  (CFStringRef)postParams, NULL,(CFStringRef)@" !%?$#[]/+:@;*()'\"",kCFStringEncodingUTF8));
postParams = escapeParams;
NSString * getParams = ...;

// Code to call API.
.
.   // Setting up url and NSMutableURLRequest
.
NSData *myRequestData = [NSData dataWithBytes:[postParams UTF8String] length:[postParams length]];
[request setHTTPBody:myRequestData];

4 个答案:

答案 0 :(得分:1)

这是一个复制粘贴代码段,我在我编码完美的所有项目中使用

- (NSString *)urlencode:(NSString *)val {
    NSMutableString *output = [NSMutableString string];
    const unsigned char *source = (const unsigned char *)[val UTF8String];
    int sourceLen = strlen((const char *)source);
    for (int i = 0; i < sourceLen; ++i) {
        const unsigned char thisChar = source[i];
        if (thisChar == ' '){
            [output appendString:@"+"];
        } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
                   (thisChar >= 'a' && thisChar <= 'z') ||
                   (thisChar >= 'A' && thisChar <= 'Z') ||
                   (thisChar >= '0' && thisChar <= '9')) {
            [output appendFormat:@"%c", thisChar];
        } else {
            [output appendFormat:@"%%%02X", thisChar];
        }
    }
    return output;
}

我建议您使用NSString分类

标题

//#import "NSString+UrlEncode.h"
#import <Foundation/Foundation.h>

@interface NSString (UrlEncode)
- (NSString *)urlencode;
@end

实施

//#import "NSString+UrlEncode.m"
#import "NSString+UrlEncode.h"

@implementation NSString (UrlEncode)
- (NSString *)urlencode {
    NSMutableString *output = [NSMutableString string];
    const unsigned char *source = (const unsigned char *)[self UTF8String];
    int sourceLen = strlen((const char *)source);
    for (int i = 0; i < sourceLen; ++i) {
        const unsigned char thisChar = source[i];
        if (thisChar == ' '){
            [output appendString:@"+"];
        } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
                   (thisChar >= 'a' && thisChar <= 'z') ||
                   (thisChar >= 'A' && thisChar <= 'Z') ||
                   (thisChar >= '0' && thisChar <= '9')) {
            [output appendFormat:@"%c", thisChar];
        } else {
            [output appendFormat:@"%%%02X", thisChar];
        }
    }
    return output;
}
@end

使用方法: 导入类别

#import "NSString+UrlEncode.h"

然后

  param.urlencode 

答案 1 :(得分:0)

=也需要进行转义(网址编码)。

请参阅此answer,了解如何正确编码("!*'();:@&=+$,/?%#[]\" ")。

答案 2 :(得分:0)

我使用了一种解决方法。

我使用alex-i的答案来转义字符串并调用API以保存在数据库中。

NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (__bridge CFStringRef) unescapedURL,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8));

每当我从数据库中获取它时,我会在url字符串中将%26替换为&

答案 3 :(得分:-1)

可能有效的问题的简单解决方案不是使用application/x-www-urlformencoded内容类型,而是使用JSON。也就是说,将application/json指定为HTTP请求中Content-Type标头的值,并将参数作为JSON发送:

因此,首先从您的参数创建一个JSON:

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

NSDictionary* params = @{@"imageUrl": url, @"realName": name};

NSError* error;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];

将JSON数据作为请求数据传递。

注意:

将POST参数发送为application/x-www-urlformencoded需要正确编码的参数。如何对参数进行precent编码可能是SO上最错误回答的问题,尽管许多错误编码的参数无论如何都会在大多数服务器上运行。

如何正确编码的权威答案在这里:

w3c指定的algorithm

我已经在SO的其他地方基于Core Foundation在Objective-C中实现了上述算法的实现,包括一个方便的方法,它将NSDictionary转换为NSData对象,正确的百分比编码。

但是,鉴于上述规范,应该很容易自己实现它 - 不使用Core Foundation或Foundation,从而依赖于Core Foundation实现,这可能会在Core Foundation更改时破坏该算法。