WKWebView加载包含特殊字符

时间:2016-03-14 14:09:07

标签: objective-c wkwebview idn

我有一个wkwebview作为浏览器。我无法使用特殊字符加载地址,例如“http://www.håbo.se”(瑞典字符)。

我正在使用:

parsedUrl = [parsedUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

这是有希望的,因为它创建一个如下所示的地址: http://www.h%c3%a5bo.se/

如果我在Chrome中输入它就可以了。但是当我尝试在wkwebview中加载它时,我得到以下内容(我可以加载所有其他页面):

这是完整的NSError打印

Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be found." UserInfo={_WKRecoveryAttempterErrorKey=<WKReloadFrameErrorRecoveryAttempter: 0x7f82ca502290>, NSErrorFailingURLStringKey=http://www.h%c3%a5bo.se/, NSErrorFailingURLKey=http://www.h%c3%a5bo.se/, NSUnderlyingError=0x7f82ca692200 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "A server with the specified hostname could not be found." UserInfo={NSErrorFailingURLStringKey=http://www.h%c3%a5bo.se/, NSErrorFailingURLKey=http://www.h%c3%a5bo.se/, _kCFStreamErrorCodeKey=8, _kCFStreamErrorDomainKey=12, NSLocalizedDescription=A server with the specified hostname could not be found.}}, 

1 个答案:

答案 0 :(得分:2)

这个很复杂。来自this article

解析域名

  

如果表示域名的字符串不是Unicode,则为   用户代理将字符串转换为Unicode。然后执行一些   字符串上的规范化函数可以消除歧义   可能存在于Unicode编码文本中。

     

规范化涉及转换大写字符等内容   小写,减少替代表示(例如转换   半宽假名到完全),消除禁止的字符(例如   空间)等。

     

接下来,用户代理转换每个标签(即文本片段)   在Unicode字符串中的点之间)到punycode表示。一个   特殊标记(&#39; xn - &#39;)被添加到每个标签的开头   包含非ASCII字符以显示标签不是   最初的ASCII。最终结果不是非常用户友好,但是   使用时准确地表示原始字符串   只有以前允许使用域名的字符。

例如,关注域名:

  

JP纳豆。例.JP

转换为下一个表示形式:

  

xn--jp-cd2fp15c.xn--fsq.jp

您可以使用following code执行此转换。

解决路径

  

如果字符串是由用户输入或存储在非Unicode中   编码,它被转换为Unicode,使用Unicode进行规范化   规范化表格C,并使用UTF-8编码进行编码。

     

然后,用户代理将非ASCII字节转换为percent-escapes。

例如,路径如下:

  

/ DIR1 /引き割りhtml的

转换为下一个表示形式:

  

/dir1/%E5%BC%95%E3%81%8D%E5%89%B2%E3%82%8A.html

为此,您可以使用以下代码:

path = [URL.path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];

请注意,stringByAddingPercentEscapesUsingEncoding:已弃用,因为每个网址组件或子组件对哪些字符有效都有不同的规则。

全部放在一起

结果代码:

@implementation NSURL (Normalization)

- (NSURL*)normalizedURL {
    NSURLComponents *components = [NSURLComponents componentsWithURL:self resolvingAgainstBaseURL:YES];
    components.host = [components.host IDNAEncodedString]; // from https://github.com/OnionBrowser/iOS-OnionBrowser/blob/master/OnionBrowser/NSStringPunycodeAdditions.h
    components.path = [components.path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
    return components.URL;
}

@end

不幸的是,实际网址&#34;规范化&#34;更复杂 - 您还需要处理所有剩余的URL组件。但我希望我已经回答了你的问题。