【问题标题】:Urlencode in Objective-CObjective-C 中的 Urlencode
【发布时间】:2013-12-25 22:02:04
【问题描述】:

我正在尝试使用此函数对长字符串进行 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;,. ????????????") 和

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

【问题讨论】:

  • 使用stringByAddingPercentEscapesUsingEncoding:有什么问题吗?
  • @HotLicks 是的,这不会百分比转义某些字符(特别是 +& 是有问题的)。你应该使用CFURLCreateStringByAddingPercentEscapes

标签: objective-c utf-8 urlencode


【解决方案1】:

您没有向我们展示您是如何创建 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 specsapplication/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] 文本!@# & (|'l;,.??? 2013-12-25 18:20:16.397 PercentEncodeTest[67199:70b] 文本%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] 文本!@# & (|'l;,.???

如您所见,string2 完全被转义,应该被正确传输。当我们转换回NSUTF8StringEncoding 时,我们的表情符号恢复正常。

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

【讨论】:

  • 工作得很好,但如果我的字符串中有笑脸,同样的问题如何解决
  • 可能取决于服务器。从技术上讲,域现在几乎可以是任何 Unicode 字符。 (例如,俄罗斯是一个在西里尔语中流行 URL 的地方。)但并非所有软件都能很好地处理这一点。
  • @Fawaz 笑脸字符已正确编码(如我修改后的答案所示)。问题是“如果有笑脸,同样的问题”是什么意思。使用这种百分比转义编码,您应该能够发送这些字符串并且不会让它们过早终止或发生任何不愉快的事情。问题是你的服务器对这个字符串做了什么。
【解决方案2】:

从 iOS9 开始,

[url_string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多