【问题标题】:Issue in sending POST parameter from iOS从 iOS 发送 POST 参数的问题
【发布时间】:2014-03-16 08:58:40
【问题描述】:

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

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

转义参数的代码:

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];

【问题讨论】:

  • 服务器能处理什么?
  • @Wain 请解释您的要求。我不明白。
  • 你可以使用身体数据吗?可以使用 JSON 吗?请求中还发布了哪些内容?
  • 也许如果您发布您的 POST 代码,我们可以提供更多帮助。与您的代码进行比较。 stackoverflow.com/questions/3566516/…
  • @alexandresoli 我用我试过的代码更新了问题。

标签: ios iphone objective-c nsurlconnection nsurlrequest


【解决方案1】:

这是我在所有项目中使用的复制粘贴代码 sn-p,它完美编码

- (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 

【讨论】:

  • 这“几乎”是正确的。根据 w3c 规范,这些未保留字符“*”、“-”、“.”、“0”到“9”、“A”到“Z”、“_”、“a”到"z" 不得转义。
  • 波浪号需要特别注意:根据定义 URI 规则的RFC 3986,波浪号不应由 URI 生产者创建。因此它也应该被转义。因此,当对 URI 参数(并且仅是一个 URI)进行百分比编码时,我们可能还想转义波浪号。
【解决方案2】:

= 也需要转义(url 编码)。

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

【讨论】:

  • 我试过了。它将http://graph.facebook.com/1005465768888979/picture?width=250&amp;height=250 转换为http%3A%2F%2Fgraph.facebook.com%2F1005465768888979%2Fpicture%3Fwidth%3D250%26height%3D250。它不工作。下载后给出零图像。我更改了一个值,因为我无法提供正确的 url。
  • @Geek 当我访问 graph.facebook.com/1005465768888979/… 时,我在 json (OAuthException) 中收到错误。确保您进行身份验证并将身份验证参数发送到 facebook。
  • 老兄,我在评论中指定我已经修改了 url 中的值,因为它是 Facebook 个人资料图片 url,所以我不能公开它。我已更改 Facebook id 值以使其无效。我只是想向您展示逃脱的字符。如果您知道如何获取您的 Facebook 帐户 ID,那么您可以使用与您的 ID 相同的网址在浏览器中加载。
  • 编码后的 url 看起来很好.. 你得到一个 nil 图像,因为响应不是有效的图像。查看NSData 响应(将其转换为NSStringNSLog 或放置断点)以了解问题所在。
【解决方案3】:

我使用了一种解决方法。

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

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

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

【讨论】:

    【解决方案4】:

    对于您的问题,一个可能有效的简单解决方案是不使用 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 数据作为您的请求数据传递。

    注意:

    application/x-www-urlformencoded 发送 POST 参数需要正确编码的参数。如何对参数进行优先编码可能是 SO 上回答最错误的问题,尽管许多错误编码的参数在大多数服务器上都可以正常工作。

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

    w3c 指定的algorithm

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

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

    【讨论】:

    • 当有问题的字符在 JSON 数据中时会发生什么?这并不能解决问题。
    • application/x-www-url-formencoded 不同,JSON 不需要百分比编码。所以,严格来说,当有一个 valid URI,它按照RFC 3986 指定的正确百分比编码时,这个(ASCII)字符串可以按原样放入 JSON 中。另一方面,当使用 x-www-form-urlencoded 内容类型时,这个已经正确编码的 URI 需要按照 w3c 的规定再次编码。这种使用不同编码算法的“双百分比编码”可能会导致问题。
    猜你喜欢
    • 1970-01-01
    • 2018-01-27
    • 2018-09-26
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多