Objective-C中的Urlencode

Faw*_*waz 2 objective-c urlencode utf-8

我正在尝试使用此函数使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"];
Run Code Online (Sandbox Code Playgroud)

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

("Text!@#&( |'l;,.")和<smile faces

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

Rob*_*Rob 8

你没有向我们展示你是如何创建MyData变量或它是什么类型的,但我猜NSString你可能已经构造了类似如下的东西:

NSString *myString = [NSString stringWithFormat:@"%@=%@", parameterKey, parameterValue];
NSData   *postData = [myString dataUsingEncoding:NSUTF8StringEncoding];
Run Code Online (Sandbox Code Playgroud)

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

NSString *myString = [NSString stringWithFormat:@"%@=%@", parameterKey, [self percentEScapeString:parameterValue]];
NSData   *postData = [myString dataUsingEncoding:NSUTF8StringEncoding];
Run Code Online (Sandbox Code Playgroud)

哪里

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

从技术上讲,每W3C的规范application/x-www-form-urlencoded,你应该替换空格+字符,因此:

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

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

无论如何,你动心使用stringByAddingPercentEscapesUsingEncoding,因为这不会给你所需要的控制.你真的需要使用CFURLCreateStringByAddingPercentEscapes,如上所示.


你问过表情符号.上面的百分比逃逸与表情符号一起工作正常.例如,考虑:

NSString *string1 = @"Text !@# & ( | 'l;,. ";
NSString *string2 = [self percentEscapeString:string1];
NSString *string3 = [string2 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", string1);
NSLog(@"%@", string2);
NSLog(@"%@", string3);
Run Code Online (Sandbox Code Playgroud)
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,我们的表情符号会恢复正常.

我怀疑现在的问题不在于表情符号是正确的百分比转义,而是你在目的地使用它们.