开发者

How to change the character encoding in UIWebView?

开发者 https://www.devze.com 2023-02-10 04:44 出处:网络
Summary of the problem: When browsing non-English sites that does not explicitly specify the correct character encoding with UIWebView on the iOS, the page cannot be displayed correctly.

Summary of the problem: When browsing non-English sites that does not explicitly specify the correct character encoding with UIWebView on the iOS, the page cannot be displayed correctly.

Detailed explanation: As the loadRequest: method in UIWebView will use the encoding specified in the charset header sent from the web server or the charset written in the HTML meta tag, and default to iso-8859-1 (well, I am not too sure about this) when charset is not specified, which cause non-English sites cannot display properly.

I have tried to Google for a way to change the charset that the UIWebView use, but the only way is to use the loadData:MIMEType:textEncodingName:baseURL: method to specify the encoding name.

However, it 开发者_如何学Pythonis not a good idea to use loadData:MIMEType:textEncodingName:baseURL: + NSURLConnection instead of loadRequest:, because UIWebView won't call the delegate method webView:shouldStartLoadWithRequest:navigationType: for frames, and even if we found a way to get notified when UIWebView load a frame, we cannot call loadData:MIMEType:textEncodingName:baseURL: to load the frame content, because it will load the frame as the outer page if we do that.

Besides, I have tried to use a javascript hack, but seems that property is read-only and cannot be changed.

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

Another workaround is inserting a meta tag to the HTML, and ask UIWebView to load the modified code, but the frame problem mentioned above also apply here.

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

Question: Is there any better solution that can change the character encoding in a loaded webpage in UIWebView, and handle frames properly?


You can do this by manually loading the HTML, modifying it, and then loading the modified content into the UIWebView.

  • manually load the HTML from the page that doesn't include the meta tag, into a string (e.g. use NSURLConnection)
  • using string manipulation, insert your appropriate encoding meta tag into the manually loaded HTML
  • set the HTML in your web view to the modified string using loadHTMLString:

Now, this will work fine for a web page that contains no links. If it contains links, then you will find that after they click on a link, the new page will not have your modification in place. Therefore, you will need to manually intercept all of the clicks. Here's how you can do that:

  • Implement a UIWebView delegate
  • Implement the method webView:shouldStartLoadWithRequest:navigationType:
  • In your delegate method, load the URL manually and modify the content before setting it into the UIWebView, as above.


This is what I do,
first find out if it is text, if it is, I get the data, set the encoding and load it using UIWebView>loadData:MIMEType:textEncodingName:baseURL.
Here is the code:

  1. Get the MIMEType sending a synchronous HEAD request.
    We want to use a HEAD HTTP request which generally is fast enough.
    And we want to make the request synchronously for two reasons, we need the request's result to continue, and we want to avoid concurrent request problems 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];
    

       


  2. Then if it is text, load it with UIWebView>loadData:MIMEType:textEncodingName:baseURL
    To maintain the application responsive, it is recommended to put the following code into a block and run it inside a GCD queue.

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

精彩评论

暂无评论...
验证码 换一张
取 消