将UITextView / UITextField中的空格编码为URL格式

时间:2009-05-27 18:54:20

标签: iphone nsstring uitextfield uitextview urlencode

我正在尝试将UITextView或UITextField的内容作为参数发送到php文件

NSString *urlstr = [[NSString alloc] initWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@",nameField.text, tagsField.text, dreamEntry.text];

当我记录urlstr时,只要UITextView或UITextField不包含空格,url格式就可以了。我如何将空格转换为%20?

修改

这是目前的代码,它不仅崩溃,而且还没有正确编码url。

name = John Doe& tags =经常出现的噩梦& entry =测试测试测试

转换为

name = John -1844684964oe& tags = recurringightmare& entry = Testing 4.214929e-307sting -1.992836e + 00sting

- (IBAction)sendButtonPressed:(id)sender
{

    NSString *urlString = [[NSString alloc] initWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@", nameField.text, tagsField.text, dreamEntry.text];

    NSString *encodedString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    NSURL *url = [[NSURL alloc] initWithString:encodedString];

    NSLog(encodedString);

    NSLog(urlString);

    [urlString release];
    [url release];
    [encodedString release];


}

3 个答案:

答案 0 :(得分:20)

实际上,以前的所有答案都包含至少一些不准确之处,对于TextFields中用户提供的文本的许多常见值,这些不准确都无法与服务器正确通信

stringByAddingPercentEscapesUsingEncoding:%会转义所有不是有效网址字符的字符。此方法应该对整个URL应用一次。

之前的回答声称stringByAddingPercentEscapesUsingEncoding:的工作方式类似于许多脚本语言中的URL构建类,您不应将其应用于整个URL字符串,但事实并非如此。任何人都可以通过检查未输入的&?的输出来轻松验证这一点。因此可以应用于整个字符串,但仅适用于“动态”网址内容。

之前的答案是正确的,你必须对进入CGI查询字符串的名称和值做更多的工作。由于CGI由RFC3875指定,因此通常称为RFC3875%转义。它确保您的姓名和值不包含有效网址字符的字符,但在网址的其他部分(;?:,{{1 }},@&=$+{}< ,和>

但是,通过在完整字符串上执行普通URL百分比转义来确保字符串中的所有字符都是有效的URL字符,这一点非常重要。虽然在示例中没有,但一般情况下,字符串的“静态”部分中可能存在无效URL字符的字符,因此您也需要将其转义。

不幸的是,,并没有让我们有权逃脱RFC3875重要字符,因此我们必须深入NSString才能这样做。显然使用CFString是一种痛苦,因此我通常会在CFString上添加Category,如下所示:

NSString

使用此@interface NSString (RFC3875) - (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding; @end @implementation NSString (RFC3875) - (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding { CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding(encoding); NSString *rfcEscaped = (NSString *)CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)self, NULL, (CFStringRef)@";/?:@&=$+{}<>,", cfEncoding); return [rfcEscaped autorelease]; } @end ,可以通过以下方式正确解决原始问题:

Category

这是一个小变量重,只是更清楚。另请注意,提供给NSString *urlEscapedBase = [@"http://server.com/file.php" stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]; NSString *rfcEscapedName = [nameField.text stringByAddingRFC3875PercentEscapesUsingEncoding: NSUTF8StringEncoding]; NSString *rfcEscapedTags = [tagsField.text stringByAddingRFC3875PercentEscapesUsingEncoding: NSUTF8StringEncoding]; NSString *rfcEscapedEntry = [dreamEntry.text stringByAddingRFC3875PercentEscapesUsingEncoding: NSUTF8StringEncoding]; NSString *urlStr = [NSString stringWithFormat:@"%@?name=%@&tags=%@&entry=%@", urlEscapedBase, rfcEscapedName, rfcEscapedTags, rfcEscapedEntry]; NSURL *url = [NSURL URLWithString:urlStr]; 的变量列表不应该stringWithFormat:终止。格式字符串描述了应遵循的变量的精确数量。此外,从技术上讲,查询字符串名称(名称,标签,条目,...)的字符串应该通过nil运行,但在这个小例子中我们可以很容易地看到它们不包含无效的URL字符。

要了解以前的解决方案不正确的原因,请假设stringByAddingPercentEscapesUsingEncoding:中的用户输入文本包含dreamEntry.text,这不太可能。使用以前的解决方案,当服务器获得该文本时,该字符后面的所有文本都将丢失,因为未转义的&符号将被服务器解释为结束该查询字符串对的值部分。

答案 1 :(得分:14)

你不应该对整个字符串进行URL转义,你应该对动态组件进行URL转义。尝试

NSString *urlStr = [NSString stringWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@",
                        [nameField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
                        [tagsField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
                        [dreamEntry.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
                        nil];
NSURL *url = [NSURL URLWithString:urlStr];

你的代码的第二个问题(毫无疑问是奇数打印的原因)是你将字符串直接传递给NSLog,所以它被视为格式字符串。你需要使用

NSLog(@"%@", encodedString);

代替。这将使其按预期打印。

编辑:你的代码的第三个问题是你混合了自动释放和拥有的对象,然后在最后释放它们。去看看你创建的3个对象,以及随后发布的对象。其中一个不应该在以后发布,因为它是由一个不以“alloc”,“copy”或“new”开头的方法生成的。识别有问题的对象是留给读者的一个练习。

答案 2 :(得分:0)

您可以使用您的网址并使用:

NSString *urlStr = [[NSString alloc] initWithFormat:@"http://server.com/file.php?name=%@&tags=%@&entry=%@",nameField.text, tagsField.text, dreamEntry.text];

NSString *encStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];