it-swarm-ru.tech

Как изменить кодировку символов в UIWebView?

Краткое описание проблемы: При просмотре неанглоязычных сайтов, в которых явно не указана правильная кодировка символов с помощью UIWebView на iOS, страница не может отображаться правильно.

Подробное объяснение: Поскольку метод loadRequest: в UIWebView будет использовать кодировку, указанную в заголовке кодировки, отправленной с веб-сервера, или кодировку, записанную в метатеге HTML, и по умолчанию 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, но кажется, что свойство доступно только для чтения и не может быть изменено.

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

Другой обходной путь - вставка метатега в HTML и запрос UIWebView загрузить измененный код, но упомянутая выше проблема с фреймами также применима и здесь.

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

Вопрос: Есть ли лучшее решение, которое может изменить кодировку символов в загруженной веб-странице в UIWebView и правильно обрабатывать фреймы?

21
howanghk

Это можно сделать, загрузив HTML-код вручную, изменив его, а затем загрузив измененный контент в UIWebView.

  • вручную загрузить HTML-код со страницы, не содержащей метатег, в строку (например, использовать NSURLConnection)
  • используя строковые манипуляции, вставьте соответствующий метатег кодирования в загруженный вручную HTML
  • установите HTML в вашем веб-представлении на измененную строку, используя loadHTMLString:

Теперь это будет хорошо работать для веб-страницы, которая не содержит ссылок. Если он содержит ссылки, то вы обнаружите, что после того, как они нажмут на ссылку, на новой странице не будет вашей модификации. Поэтому вам нужно будет вручную перехватывать все клики. Вот как вы можете это сделать:

  • Реализовать делегат UIWebView
  • Реализуйте метод webView: shouldStartLoadWithRequest: navigationType:
  • В вашем методе делегата загрузите URL-адрес вручную и измените содержимое, прежде чем устанавливать его в UIWebView, как описано выше.
6
Simon Woodside

Вот что я делаю,
сначала выясняю, является ли это текстом; если да, я получаю данные, устанавливаю кодировку и загружаю их, используя UIWebView>loadData:MIMEType:textEncodingName:baseURL.
Вот код:

  1. Получите MIMEType, отправляющий синхронный запрос HEAD.
    Мы хотим использовать HTTP-запрос HEAD, который как правило, достаточно быстрый .
    И мы хотим сделать запрос синхронно по двум причинам, нам нужно, чтобы результат запроса продолжался, и мы хотим избежать одновременных проблем запроса как это .

     
    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. Затем, если это текст, загрузите его с помощью IWebView> loadData: MIMEType: textEncodingName: baseURL
    Для обеспечения поддержки приложения, рекомендуется поместить следующий код в блок и запустить его в очередь GCD .

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