【问题标题】:Encoding string arguments for URLs为 URL 编码字符串参数
【发布时间】:2009-08-09 00:04:47
【问题描述】:

我创建了一个为我构建 URL 的方法。

- (NSString *)urlFor:(NSString *)path arguments:(NSDictionary *)args
{
    NSString *format = @"http://api.example.com/%@?version=2.0.1";
    NSMutableString *url = [NSMutableString stringWithFormat:format, path];

    if ([args isKindOfClass:[NSDictionary class]]) {
        for (NSString *key in args) {
            [url appendString:[NSString stringWithFormat:@"&%@=%@", key, [args objectForKey:key]]];
        }
    }

    return url;
}

当我尝试构建类似下面的内容时,URL 没有被编码,当然。

NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:
                            @"http://other.com", @"url",
                            @"ABCDEF", @"apiKey", nil];

NSLog(@"%@", [self urlFor:@"articles" arguments:args]);`

返回值是http://api.example.com/articles?version=2.0.1&url=http://other.com&apiKey=ABCDEF,而应该是http://api.example.com/articles?version=2.0.1&url=http%3A%2F%2Fother.com&apiKey=ABCDEF

我需要同时编码键和值。我搜索了一些东西,发现 CFURLCreateStringByAddingPercentEscapesstringByAddingPercentEscapesUsingEncoding 但我所做的测试都没有奏效。

我该怎么做?

【问题讨论】:

  • 对不起!我的代码破坏了语法突出显示,我无法修复它!有人吗?

标签: objective-c cocoa


【解决方案1】:

IIRC,当斜杠位于 URL 的查询部分时,应正确解释它们。您是否测试过它是否仍然可以在没有编码斜杠的情况下工作?否则,请执行以下操作:

if ([args isKindOfClass:[NSDictionary class]]) {
        for (NSString *key in [args allKeys]) {
            NSString *value = [(NSString*)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)[args objectForKey:key], NULL, CFSTR("/?&:=#"), kCFStringEncodingUTF8) autorelease];
            [url appendString:[NSString stringWithFormat:@"&%@=%@", key, value]];
            [value release];
        }
}

return url;

注意 CFURLCreateStringByAddingPercentEscapes 的第四个参数的值。

【讨论】:

  • 第一个问题:第4个参数可以接受任何需要编码的字符吗?
  • 是的。来自文档: legalURLCharactersToBeEscaped 要转义的合法字符。传递 NULL 以指定不替换任何合法字符。只有少数几个字符无法逃脱,但我选择了安全路线,因为我懒得去查找那些是哪些字符(尽管这可能是个好主意)。
  • 这会泄漏内存。 value 是一个拥有的对象,被丢弃而不被释放。
  • 你是对的;我会编辑它。不敢相信我把它搞砸了……
  • 这实际上是糟糕的代码(截至目前)。我认为记忆的东西有点混乱。查看这个问题以获得更好/更新的代码:stackoverflow.com/questions/718429/…
【解决方案2】:

您应该考虑使用Google Toolbox for Mac's GTMNSString+URLArguments;它正是为此目的而设计的。

【讨论】:

  • 我会检查 GTM。显然这个库是一个很好的库,因为 SO 上的每个问题都提到了它。
【解决方案3】:

我会推荐我们的KSFileUtilities 课程集。您的示例将是:

- (NSString *)urlFor:(NSString *)path arguments:(NSDictionary *)args
{
    NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:args];
    [parameters setObject:@"2.0.1" forKey:@"version"];

    NSURL *result = [NSURL ks_URLWithScheme:@"http"
                                       host:@"api.example.com"
                                       path:path
                            queryParameters:parameters;

    return [result absoluteString];
}

【讨论】:

    猜你喜欢
    • 2012-06-02
    • 1970-01-01
    • 2021-03-17
    • 2018-05-06
    相关资源
    最近更新 更多