如何更改 UIWebView 中的字符编码?

Posted

技术标签:

【中文标题】如何更改 UIWebView 中的字符编码?【英文标题】:How to change the character encoding in UIWebView? 【发布时间】:2011-02-11 19:18:42 【问题描述】:

问题总结:ios上浏览没有用UIWebView明确指定正确字符编码的非英文网站时,页面无法正确显示。

详解:由于UIWebView中的loadRequest:方法会使用web服务器发送的charset header中指定的编码或者html meta标签中写入的charset,默认为iso- 8859-1(好吧,我不太确定)当未指定字符集时,这会导致非英文网站无法正常显示。

我曾尝试通过 Google 寻找一种方法来更改 UIWebView 使用的字符集,但唯一的方法是使用 loadData:MIMEType:textEncodingName:baseURL: 方法来指定编码名称。

但是,使用loadData:MIMEType:textEncodingName:baseURL: + NSURLConnection 代替loadRequest: 并不是一个好主意,因为UIWebView 不会为帧调用委托方法webView:shouldStartLoadWithRequest:navigationType:,即使我们找到了一种方法来获得通知时UIWebView 加载框架,我们不能调用loadData:MIMEType:textEncodingName:baseURL: 来加载框架内容,因为如果我们这样做,它会将框架加载为外部页面。

此外,我曾尝试使用 javascript hack,但似乎该属性是只读的,无法更改。

[webView stringByEvaluatingJavaScriptFromString:@"document.characterSet='utf-8';"];  

另一种解决方法是在 HTML 中插入一个 meta 标签,并要求 UIWebView 加载修改后的代码,但上面提到的框架问题在这里也适用。

<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

问题:有没有更好的解决方案可以在UIWebView中改变加载网页中的字符编码,并正确处理帧?

【问题讨论】:

请在此处提供您的网址,然后让我检查。 你对网页或服务器有控制权吗? @magnus 太容易了 ;) 【参考方案1】:

您可以通过手动加载 HTML,对其进行修改,然后将修改后的内容加载到 UIWebView 中来做到这一点。

手动将页面中不包含元标记的 HTML 加载到字符串中(例如使用 NSURLConnection) 使用字符串操作,将适当的编码元标记插入到手动加载的 HTML 中 使用loadHTMLString: 将Web 视图中的HTML 设置为修改后的字符串

现在,这适用于不包含链接的网页。如果它包含链接,那么您会发现在他们单击链接后,新页面将不会有您的修改。因此,您将需要手动拦截所有点击。您可以这样做:

实现 UIWebView 委托 实现方法webView:shouldStartLoadWithRequest:navigationType: 在您的委托方法中,手动加载 URL 并修改内容,然后再将其设置到 UIWebView,如上。

【讨论】:

您是否也会收到帧的委托回调? 根据文档,是的。 developer.apple.com/library/IOs/#documentation/UIKit/Reference/… 您是如何“在将内容设置到 UIWebView 之前修改内容”的? loadHTMLString 无法加载到特定框架中,但始终加载到根文档中。【参考方案2】:

这就是我的工作, 首先找出它是否是文本,如果是,我获取数据,设置编码并使用UIWebView&gt;loadData:MIMEType:textEncodingName:baseURL加载它。 代码如下:

    获取发送同步 HEAD 请求的 MIMEType。 我们想使用generally is fast enough 的 HEAD HTTP 请求。 而我们想要同步请求有两个原因,我们需要请求的结果继续,我们想避免并发请求问题like this。

     
    NSMutableURLRequest *headRequest = [NSMutableURLRequest requestWithURL:url];
    [headRequest setHTTPMethod:@"HEAD"];
    NSHTTPURLResponse *headResponse;
    NSError *error = nil;
    [NSURLConnection sendSynchronousRequest:headRequest
                          returningResponse:&headResponse
                                      error:&error];
    if (error != nil) 
        NSLog(@"loadURLWithString %@",[error localizedDescription]);
    
    NSString *mimeType = [headResponse MIMEType];
    


    然后如果是文本,用UIWebView>loadData:MIMEType:textEncodingName:baseURL加载它 为了保持应用程序的响应性,建议将以下代码放入一个块中并在GCD queue 中运行它。

    
    if([mimeType rangeOfString:@"text"
                       options:NSCaseInsensitiveSearch].location == 0) 
    
       [wview loadData:[NSData dataWithContentsOfURL: url] MIMEType:mimeType
            textEncodingName:encoding baseURL:nil];
    

【讨论】:

感谢您的回答。但是,这仅适用于根文档。如果有 iframe 或框架集,它将无法工作。请阅读第 4 段了解为什么它没有解决问题的更多详细信息。 此外,使用同步请求和 -[NSString initWithContentsOfURL] 非常不鼓励,因为它会阻塞您的主线程,或者您必须将它们分派到后台线程中。生成线程是一项相当昂贵的操作,因此异步请求是一种更好的方法。 更新了答案。没有尝试过使用 iframe 或框架集的文档,但是这种方法对我很有用,并且可能对其他人有用。至于第二条评论,我使用 GCD 和 blocks 来避免阻塞主线程或产生线程。 encoding.spec.whatwg.org/#names-and-labels。了解可能的编码名称选项的有用链接。

以上是关于如何更改 UIWebView 中的字符编码?的主要内容,如果未能解决你的问题,请参考以下文章

加载新的 html 字符串时如何防止 UIWebView 滚动到顶部?

python中的字符串编码问题——4.unicode编解码(以实际工作中遇到的韩文编码为例)

如何在 iOS 的 UIWebView 中更改数字和电子邮件的颜色?

Unicode字符列表的Unicode 编码表

UnicodeEncodeError:“UCS-2”编解码器无法对位置 8-8 中的字符进行编码:Tk 中不支持非 BMP 字符 [重复]

字符编码及文件操作