NSURL returning nil for certain cases

2020-04-21 05:25发布

问题:

I'm creating an NSURL to send as a request to a PHP rest API that I've got setup. Here's my code below:

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];

For some reason though, the address variable holds nil whenever I try to make the following url happen:

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

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?

回答1:

You said:

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?

Yes, in your PHP code, if you are using single quotation marks around your string values, then you have to escape any ' characters that appear in your string literals.

But it is not the case that you should be using \ character to escape ' characters that appear in the values you are trying to pass in the URL of your request. (Nor should you do so in the body of a POST request.)

And if you are tempted to escape these ' characters because you're inserting these values into SQL statements, you should not be manually escaping them. Instead you should call mysqli_real_escape_string or explicitly bind values to ? placeholders in your SQL. Never rely upon the client code to escape these values (because you'd still be susceptible to SQL injection attacks).

Getting back to the encoding of reserved characters in a URL, this is governed by RFC 3986. The prudent strategy is to percent escape any character other than those in the unreserved character set. Notably, if your values might include & or + characters, the percent escaping is critical.

Thus, the correct encoding of the ' character in a URL query value is not \' but rather %27. Unfortunately, encoding stringByAddingPercentEscapesUsingEncoding is not sufficient, though (as it will let certain critical characters go unescaped in the value strings).

The historically, we'd percent escape value using CFURLCreateStringByAddingPercentEscapes (see Urlencode in Objective-C). The stringByAddingPercentEncodingWithAllowedCharacters, introduced in Mac OS 10.9 and iOS 7, can work, too (see https://stackoverflow.com/a/24888789/1271826 for an illustration of the possible character sets).