我正在尝试将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];
}
答案 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];