使用 Objective-C 对字符串进行 URLEncoding

发布于 2024-08-28 03:07:51 字数 1345 浏览 6 评论 0原文

我正在尝试对字符串进行 URL 编码以形成来自 Objective-C 的 GET 请求。

NSString *params = @"'Decoded data!'/foo.bar:baz";

NSRunAlertPanel( @"Error", [params urlEncoded], @"OK", nil, nil );

这是扩展 NSString 的类别,

    -(NSString *) urlEncoded
{
    NSString *encoded = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                                                   NULL,
                                                   (CFStringRef)self,
                                                   NULL,
                                                   (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                   kCFStringEncodingUTF8 );
    return encoded;
}

返回

1606410046ecoded          1606410784ata2270.000000foo.bar0X1.001716P-1042baz

所以我第一次运行它时,我从对话框中

。在我再次运行它后,我立即得到这个

1606410046ecoded          1606410944ata227369374562920703448982951250259562309742470533728899744288431318481119278377104028261651081181287077973859930826299575521579020410425419424562236383226511593137467590082636817579938932512039895040.000000foo.bar0X1.66E6156303225P+771baz

然后,如果我再次运行它,它会返回到第一个。真的很奇怪。

如果 params 设置为 @"&"或 @" " 我只是在对话框中返回一个“2”(不带引号)。

还有一种方法可以让 % 符号显示在警报对话框中?

谢谢

I'm trying to URL encode a string to form a GET request from objective-c.

NSString *params = @"'Decoded data!'/foo.bar:baz";

NSRunAlertPanel( @"Error", [params urlEncoded], @"OK", nil, nil );

This is the category extending NSString

    -(NSString *) urlEncoded
{
    NSString *encoded = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                                                   NULL,
                                                   (CFStringRef)self,
                                                   NULL,
                                                   (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                   kCFStringEncodingUTF8 );
    return encoded;
}

So the first time I run it I get back

1606410046ecoded          1606410784ata2270.000000foo.bar0X1.001716P-1042baz

from the dialog box.

Immediately after I run it again I get this

1606410046ecoded          1606410944ata227369374562920703448982951250259562309742470533728899744288431318481119278377104028261651081181287077973859930826299575521579020410425419424562236383226511593137467590082636817579938932512039895040.000000foo.bar0X1.66E6156303225P+771baz

Then if I run it AGAIN it goes back to the first one. It's really weird.

If params is set to @"&" or @" " I just get back a "2" (w/o the quotes) in the dialog box.

Also is there a way I can have the % signs be shown in the alert dialog?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

聆听风音 2024-09-04 03:07:51

我认为 NSAlert 正在将 % 字符解释为填充有随机数据的字符串格式说明符。只需 NSLog 输出就可以了:

%27Decoded%20data%21%27%2Ffoo.bar%3Abaz

此外,您的 -urlEncoded 类别方法中存在内存泄漏。您使用包含 Create 的 CF 函数创建该字符串,因此您负责释放它。

-(NSString *) urlEncoded
{
   CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(
                                                   NULL,
                                                   (CFStringRef)self,
                                                   NULL,
                                                   (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                   kCFStringEncodingUTF8 );
    return [(NSString *)urlString autorelease];
}

I think the NSAlert is interpreting the % characters as string format specifiers which are being filled with random data. Just NSLog the output and it's fine:

%27Decoded%20data%21%27%2Ffoo.bar%3Abaz

Also, you have a memory leak in your -urlEncoded category method. You create the string using a CF function containing Create so you are responsible for releasing it.

-(NSString *) urlEncoded
{
   CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(
                                                   NULL,
                                                   (CFStringRef)self,
                                                   NULL,
                                                   (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                   kCFStringEncodingUTF8 );
    return [(NSString *)urlString autorelease];
}
满身野味 2024-09-04 03:07:51

我已经开源了我的 URL 编码器实用程序类,它可以智能地跳过 URL 的域和路径部分(以避免对斜杠等进行编码),并仅转义后面不跟有 2 位十六进制代码的百分比序列(以防止像这样的百分比双重编码:%20 -> %2520)。

它已经针对 10,000 多个 URL 进行了测试,非常强大且高性能。

您可以在此处了解有关(并下载)我的实现的更多信息...
http://jayfuerstenberg.com/devblog/url-encoding-in-objective-c

I've open sourced my URL encoder utility class which intelligently skips the domain and path portion of the URL (to avoid encoding the slashes, etc...) and escape only the percent sequences that are not followed by 2-digit hex codes (to prevent double encoding of percents like this: %20 -> %2520).

It has been tested against over 10,000 URLs and is very robust and performant.

You can learn more about (and download) my implementation here...
http://jayfuerstenberg.com/devblog/url-encoding-in-objective-c

梦冥 2024-09-04 03:07:51

通过传递字符串并使用 CFBridgingRelease 来创建实例方法,而不是使用 ARC 时不再可用的 autorelease:

- (NSString *)urlEncodeWithString: (NSString*)string
{
  CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(
                                                                  NULL,
                                                                  (CFStringRef)string,
                                                                  NULL,
                                                                  (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                                  kCFStringEncodingUTF8 );
  return (NSString *)CFBridgingRelease(urlString);
}

Rather than autorelease, which is no longer available when using ARC, create your instance method by passing a string and using CFBridgingRelease:

- (NSString *)urlEncodeWithString: (NSString*)string
{
  CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(
                                                                  NULL,
                                                                  (CFStringRef)string,
                                                                  NULL,
                                                                  (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
                                                                  kCFStringEncodingUTF8 );
  return (NSString *)CFBridgingRelease(urlString);
}
禾厶谷欠 2024-09-04 03:07:51

好吧,事实证明这不是问题。它被正确编码,因为我检查了服务器日志,似乎请求参数已被编码。

为了在对话框中正确显示编码字符串,我只是事后用 %% 替换了 % 的所有实例。

OK turns out it was a nonissue. It was being encoded correctly because I checked the server logs and it seems the request params were encoded.

And for displaying the encoded string in the dialog box correctly, I just replaced all instances of % with %% after the fact.

西瓜 2024-09-04 03:07:51

在我看来,最简单的方法是使用 NSString (NSURLUtilities) 类别提供的便捷方法

我的实现:

- (NSString *) urlEncodedString
{
    NSString *result = [self stringByReplacingOccurrencesOfString:@" " withString:@"+"];
    result = [result stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    return result;
}

In my opinion the easiest way is to use convenient method supplied with NSString (NSURLUtilities) category

My implementation:

- (NSString *) urlEncodedString
{
    NSString *result = [self stringByReplacingOccurrencesOfString:@" " withString:@"+"];
    result = [result stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    return result;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文