objective-c - Objective-C 中的网址编码

标签 objective-c utf-8 urlencode

我正在尝试使用此函数对长字符串进行 url 编码

    NSData   *PostData   = [MyString dataUsingEncoding:NSUTF8StringEncoding];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://xxxxxxx.com/save.php"]];

   [request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
   [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
   [request setHTTPBody:PostData];
   [request setHTTPMethod:@"POST"];

但是我在将它保存到我的 sql 时遗漏了一些数据 例如,如果我们有这个包含特殊字符的字符串

("Text !@# & ( | 'l;,. 😒😚😜") and < smile faces

当这个字符串接收到我的服务器时,我错过了这个 & 和笑脸之后的字符串?!

最佳答案

你没有告诉我们你是如何创建 MyData 变量的或者它是什么类型,但我猜它是一个 NSString 你可能已经构造了类似以下内容:

NSString *myString = [NSString stringWithFormat:@"%@=%@", parameterKey, parameterValue];
NSData   *postData = [myString dataUsingEncoding:NSUTF8StringEncoding];

您需要做的是“百分比转义”任何根据 RFC 3986 定义为保留的字符.因此,您可以将上面的内容替换为:

NSString *myString = [NSString stringWithFormat:@"%@=%@", parameterKey, [self percentEScapeString:parameterValue]];
NSData   *postData = [myString dataUsingEncoding:NSUTF8StringEncoding];

在哪里

- (NSString *)percentEscapeString:(NSString *)string
{ 
    return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                     (CFStringRef)string,
                                                                     NULL,
                                                                     (CFStringRef)@":/?@!$&'()*+,;=",
                                                                     kCFStringEncodingUTF8));
}

技术上,根据 the W3C specs对于 application/x-www-form-urlencoded,您应该将空格替换为 + 字符,因此:

- (NSString *)percentEscapeString:(NSString *)string
{ 
    NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                 (CFStringRef)string,
                                                                                 (CFStringRef)@" ",
                                                                                 (CFStringRef)@":/?@!$&'()*+,;=",
                                                                                 kCFStringEncodingUTF8));
    return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}

就个人而言,我将这些类型的方法放在 NSString 类别中,而不是放在当前类中,但希望这能说明这个想法。

无论如何,请不要尝试使用 stringByAddingPercentEscapesUsingEncoding,因为这无法为您提供所需的控制。您确实需要使用 CFURLCreateStringByAddingPercentEscapes,如上所示。


你问的是表情符号。上述转义百分比适用于表情符号。例如,考虑:

NSString *string1 = @"Text !@# & ( | 'l;,. 😒😚😜";
NSString *string2 = [self percentEscapeString:string1];
NSString *string3 = [string2 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", string1);
NSLog(@"%@", string2);
NSLog(@"%@", string3);
2013-12-25 18:20:16.391 PercentEncodeTest[67199:70b] Text !@# & ( | 'l;,. 😒😚😜
2013-12-25 18:20:16.397 PercentEncodeTest[67199:70b] Text%20%21%40%23%20%26%20%28%20%7C%20%27l%3B%2C.%20%F0%9F%98%92%F0%9F%98%9A%F0%9F%98%9C
2013-12-25 18:20:16.401 PercentEncodeTest[67199:70b] Text !@# & ( | 'l;,. 😒😚😜

如您所见,string2 完全经过百分比转义,应该可以正确传输。当我们转换回 NSUTF8StringEncoding 时,我们可以很好地恢复表情符号。

我怀疑现在的问题不在于表情符号正确转义的事实,而在于目的地对它们的使用。

关于objective-c - Objective-C 中的网址编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20777112/

相关文章:

r - R 如何处理 Unicode/UTF-8?

java - urlencode() 'asterisk'(星号?)字符

javascript - Chrome URL 多个空格问题

ios - 在 Objective-C 中将货币字符串转换为 float

objective-c - didChangeObject : not called of NSFetchedResultsController

ios - 从另一个 View Controller 停止dispatch_async内部的无限while循环

java - 分词和模式匹配在中文中是如何工作的?

iphone - 如何使用 UIGestureRecognizers 在多个 UIView 或 UIImageView 上进行点击、捏合和旋转

ruby-on-rails - VSCode 提示 Ruby UTF-8 文件具有无效的多字节字符 (US-ASCII)

php - URL/HTML 转义/编码