【问题标题】:Encode NSURL when query params contain ampersand当查询参数包含 & 时编码 NSURL
【发布时间】:2014-06-26 09:38:43
【问题描述】:

我正在调用 API,有时我的查询参数包含一个 & 符号。例如参数可能是name=Billy & Bob

当我创建网址时,我使用:

NSString *url = [NSString stringWithFormat:@"%@/search/%@?name=%@&page=%d", [Statics baseURL], user_id, [term urlEncodeUsingEncoding:NSUTF8StringEncoding], page];
NSURL *fullURL = [NSURL URLWithString:[url stringWithAccessToken]];

我用这种方法对 url 进行编码:

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
    return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
                                                               (CFStringRef)self,
                                                               NULL,
                                                               (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                               CFStringConvertNSStringEncodingToEncoding(encoding)));
}

问题是,& 符号通过urlEncodeUsingEncoding 方法正确编码,然后URLWithString 方法再次编码字符串,并用@987654327 替换字符串中创建的% 符号@。

任何人都知道如何编码包含&符号的查询参数?

【问题讨论】:

    标签: ios objective-c utf-8 nsurl


    【解决方案1】:

    我找到了解决方案,它是 NSURLComponents - 此时在 iOS7 中添加了一个完全未记录的类。

    NSURLComponents *components = [NSURLComponents new];
    components.scheme = @"http";
    components.host = @"myurl.com";
    components.path = [NSString stringWithFormat:@"%@/mypath/%@", @"/mobile_dev/api", user_id];
    components.percentEncodedQuery = [NSString stringWithFormat:@"name=%@", [term urlEncodeUsingEncoding:NSUTF8StringEncoding]];
    
    NSURL *fullURL = [components URL];
    

    通过使用components.percentEncodedQueryterm 元素使用了我放在它上面的编码,而苹果没有碰它。

    希望这对其他人有所帮助。

    【讨论】:

    • 这确实帮助了我更新用户个人资料并且必须同时支持和号和加号的地方。很容易转换为 Swift,然后添加此行来处理加号: components.percentEncodedQuery = components.percentEncodedQuery?.stringByReplacingOccurrencesOfString("+", withString: "%2B")
    【解决方案2】:

    我使用这样的东西:

    - (NSString *)URLEncodedStringWithSourceString:(NSString *)sourceString
    {
        NSMutableString *output = [NSMutableString string];
        const unsigned char *source = (const unsigned char *)[sourceString 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;
    }
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2015-02-11
      • 2018-01-18
      • 2012-03-07
      • 2013-10-19
      • 1970-01-01
      • 2011-09-06
      • 2020-09-24
      • 2020-07-06
      • 1970-01-01
      相关资源
      最近更新 更多