Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

  • Получить 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];
    


  • Затем, если это текст, загрузите его с помощью UIWebView > loadData: MIMEType: textEncodingName: baseURL
    Чтобы поддерживать отзывчивость приложения, рекомендуется поместить следующий код в блок и запустить его внутри очередь GCD.

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