关于objective C:NSURL 在某些情况下返回 nil

NSURL returning nil for certain cases

我正在创建一个 NSURL 作为请求发送到我已经设置好的 PHP rest API。下面是我的代码:

1
2
3
4
5
6
7
8
9
NSMutableString *url = [NSMutableString stringWithFormat:@"http://www.private.com/recievedata.php?item=%@&contact=%@&discovery=%@&summary=%@",__item,__contactDetails,__lostFound,__explain];

//The" '" in PHP is a special character, so we have to escape it in the URL
//The two slashes are because the"" itself is a special character in Objective C

NSString *formattedURL = [url stringByReplacingOccurrencesOfString:@"'" withString:@"\\\'"];

NSURLSession *session = [NSURLSession sharedSession];
NSURL *address = [NSURL URLWithString:formattedURL];

但由于某种原因,每当我尝试使以下 url 发生时,地址变量都会保存 nil

1
http://www.private.com/recievedata.php?item=hell\'&contact=hell&discovery=lost&summary=hell

从我的代码中可以看出,我必须在撇号前面添加 "\\\\",因为 PHP 需要在其 URL 中对 " \\' " 进行转义。但是这样做,似乎我违反了为 NSURL 设置的一些要求。大家觉得呢?


你说:

I had to add"" in front of the apostrophes as is evident from my code because PHP needs to have the" '" escaped in its URLs. But by doing so, it seems like I've violated some requirement set out for NSURL. What do you guys think?

是的,在您的 PHP 代码中,如果您在字符串值周围使用单引号,那么您必须转义出现在字符串文字中的任何 ' 字符。

但您不应该使用 \\ 字符来转义出现在您尝试在请求的 URL 中传递的值中的 ' 字符。 (您也不应该在 POST 请求的正文中这样做。)

如果您因为将这些值插入 SQL 语句而想要转义这些 ' 字符,则不应手动转义它们。相反,您应该调用 mysqli_real_escape_string 或将值显式绑定到 SQL 中的 ? 占位符。永远不要依赖客户端代码来转义这些值(因为您仍然容易受到 SQL 注入攻击)。

回到 URL 中保留字符的编码,这由 RFC 3986 管理。谨慎的策略是百分比转义除未保留字符集中的字符之外的任何字符。值得注意的是,如果您的值可能包含 &+ 字符,则转义百分比至关重要。

因此,URL查询值中'字符的正确编码不是\\'而是%27。不幸的是,编码 stringByAddingPercentEscapesUsingEncoding 是不够的(因为它会让某些关键字符在值字符串中未转义)。

过去,我们使用 CFURLCreateStringByAddingPercentEscapes 百分比转义值(参见 Objective-C 中的 Urlencode)。 Mac OS 10.9 和 iOS 7 中引入的 stringByAddingPercentEncodingWithAllowedCharacters 也可以工作(有关可能的字符集的说明,请参见 https://stackoverflow.com/a/24888789/1271826)。