代码之家  ›  专栏  ›  技术社区  ›  Geek

从iOS发送POST参数时出现问题

  •  3
  • Geek  · 技术社区  · 12 年前

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

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

    转义参数的代码:

    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 回复  |  直到 12 年前
        1
  •  1
  •   Durai Amuthan.H    12 年前

    下面是我在所有项目中使用的复制粘贴代码片段,它编码完美

    - (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 
    
        2
  •  0
  •   Community Mohan Dere    9 年前

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

    看看这个 answer 如何正确编码( "!*'();:@&=+$,/?%#[]\" " ).

        3
  •  0
  •   Geek    12 年前

    我使用了一种变通方法。

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

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

    每当我从数据库中获取它时,我都会替换 %26 具有 & url字符串中。

        4
  •  -1
  •   CouchDeveloper    12 年前

    对于您的问题,一个可能有效的简单解决方案是不使用 application/x-www-urlformencoded 内容类型,而是使用JSON。即,指定 application/json 作为 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参数发送为 应用程序/x-wwww-urlformencoded 需要正确编码的参数。如何对参数进行预编码可能是SO上回答错误最多的问题,尽管许多错误编码的参数在大多数服务器上都能正常工作。

    如何正确编码的最终答案如下:

    这个 algorithm 如w3c所规定。

    我已经将上述算法的一个实现放在了基于Core Foundation的Objective-C中,包括一个将NSDictionary转换为NSData对象的方便方法,该对象经过适当的百分比编码。

    然而,考虑到上述规范,自己实现它应该很容易,而不需要使用Core Foundation或Foundation,从而变得依赖于该Core Foundation实现,这可能会在Core Foundation更改时破坏该算法。