質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

Q&A

解決済

2回答

3179閲覧

FultterのUTF-8をdecodeできない問題の解決方法

ponyo877

総合スコア17

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

0グッド

0クリップ

投稿2021/01/23 08:33

FlutterでiOSアプリを作成している過程でHTTPのレスポンスをUTF-8でデコードできない問題が発生しており、解決したく思います。
AndroidのPixel 2のエミュレータでは問題なくデコードできていたのでiOS特有の問題であると考えています。

以下いPhone12 Pro Maxのエミュレータを使い、実行した結果になります。decoded_body_byteがnullになってしまうのが問題です。

dart

1import 'dart:async'; 2import 'dart:typed_data'; 3import 'package:flutter/material.dart'; 4import 'package:flutter/services.dart'; 5import 'package:html/dom.dart' as dom; 6import 'package:http/http.dart' as http; 7import 'package:charset_converter/charset_converter.dart'; 8import 'package:flutter_user_agent/flutter_user_agent.dart'; 9// skip 10 11String userAgent; 12try { 13 userAgent = await FlutterUserAgent.getPropertyAsync('userAgent'); 14 print("userAgent: ${userAgent}"); 15} on PlatformException { 16 userAgent = '<error>'; 17} 18var response = await http.Client().get(Uri.parse("http://news4vip.livedoor.biz/archives/52385788.html"), headers: {'User-Agent': userAgent}); 19print("Response status: ${response.statusCode}"); 20print("response.headers: ${response.headers['content-type']}"); 21String decoded_body_byte = await CharsetConverter.decode("UTF-8", response.bodyBytes); 22print("decoded_body_byte: ${decoded_body_byte}"); // ここの結果がnullになってしまうことが問題になっています。 23Uint8List encoded = await CharsetConverter.encode("UTF-8", "【画像】中日「かっこいい」今季のユニホーム発表www"); 24print("encoded.length: ${encoded.length}"); 25String decoded_body_byte_only_title = await CharsetConverter.decode("UTF-8", response.bodyBytes.sublist(71, 71 + 78)); 26print("decoded_body_byte_only_title: ${decoded_body_byte_only_title}");

上記の出力結果は以下になります。

2021-01-23 17:09:29.964984+0900 Runner[89036:14458916] flutter: userAgent: CFNetwork/1209 Darwin/20.2.0 (iPhone iOS/14.3) 2021-01-23 17:09:30.187131+0900 Runner[89036:14458916] flutter: Response status: 200 2021-01-23 17:09:30.190547+0900 Runner[89036:14458916] flutter: response.headers: text/html; charset=utf-8 2021-01-23 17:09:30.195755+0900 Runner[89036:14458916] flutter: decoded_body_byte: null 2021-01-23 17:09:30.197368+0900 Runner[89036:14458916] flutter: encoded.length: 78 2021-01-23 17:09:30.198128+0900 Runner[89036:14458916] flutter: decoded_body_byte_only_title: 【画像】中日「かっこいい」今季のユニホーム発表www

以下flutter doctorの出力結果になります。

% flutter doctor Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 1.22.5, on macOS 11.1 20C69 darwin-x64, locale ja-JP) [!] Android toolchain - develop for Android devices (Android SDK version 29.0.2) ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses [✓] Xcode - develop for iOS and macOS (Xcode 12.3) [!] Android Studio (version 4.1) ✗ Flutter plugin not installed; this adds Flutter specific functionality. ✗ Dart plugin not installed; this adds Dart specific functionality. [✓] VS Code (version 1.52.1) [✓] Connected device (2 available) ! Doctor found issues in 2 categories.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

詳細は確認していないのですが。そのページのサーバのレスポンスヘッダを見るとContent-Type: text/html; charset=euc-jpとなっています。UTF-8ではない可能性があります。

追記
質問者のコメントの通りUserAgentを指定するとUTF-8で返す仕様のサーバみたいですね。
下記のコードで検証してみましたがしっかりタイトルを取得できました。

dart

1final userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1'; 2 final client = http.Client(); 3 try { 4 var response = await client.get( 5 Uri.parse("http://news4vip.livedoor.biz/archives/52385788.html"), 6 headers: { 7 'User-Agent': userAgent, 8 }, 9 ); 10 print("response.headers: ${response.headers['content-type']}"); 11 final decoded = await CharsetConverter.decode('UTF-8', response.bodyBytes); 12 final document = dom.Document.html(decoded); 13 print(document.querySelector('title')?.text); 14 } catch (error) { 15 print('error: $error'); 16 } finally { 17 client.close(); 18 }

投稿2021/01/23 14:06

編集2021/01/24 07:18
hiroshihorie

総合スコア192

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ponyo877

2021/01/23 23:44

説明が足りず申し訳ありません。 こちらWebブラウザ用とモバイル用のためにUserAgentに依ってレスポンスの内容が変わるリクエストになっていまして、 UserAgent: CFNetwork/1209 Darwin/20.2.0 (iPhone iOS/14.3)で再度試行していただけると、 Content-Type: text/html; charset=utf-8のレスポンスが返却されるかと思います。 ご確認よろしくお願いします。
hiroshihorie

2021/01/24 07:21

UserAgentによってはUTF-8で返すみたいですね。ちょっとコード書いて検証してみましたらタイトル取得できました。質問者とほぼ同じコードなのでなぜ上手くいったのかわかりません。サーバ側がたまにデコードに失敗するデータを返している可能性もありますね。
ponyo877

2021/01/24 07:48

こちらも説明不足でしたらすみません、、 出力結果の4行目の以下のnullの部分は本来ならhtml文字列が出力されるはずなんですが、できていないことが問題になります。 ``` 2021-01-23 17:09:30.195755+0900 Runner[89036:14458916] flutter: decoded_body_byte: null ``` こちらも正常に表示されましたでしょうか?
hiroshihorie

2021/01/24 08:03

自分のコードで検証した結果、そちらも表示されました。
ponyo877

2021/01/24 10:01

なるほど、環境の設定によっても結果が異なるのでしょうか。 今回は別の方法で自己解決することができました。 情報提供ありがとうございました!
hiroshihorie

2021/01/24 11:07

了解です、やはり「サーバ側がたまにデコードに失敗するデータを返している」という事でしたか。
guest

0

自己解決

本件は返却されたHTTPレスポンスにUTF8として不正なバイトコードが含まれていたために失敗していたようです。
そこでデコーダーを以下のPluginに変更した所、想定通りにデコードすることができました。
https://api.flutter.dev/flutter/dart-convert/Utf8Codec/decode.html

dart

1String decoded = Utf8Decoder(allowMalformed: true).convert(response.bodyBytes); 2// allowMalformed: trueでUTF8の不正文字を置換オプションを有効化

ご協力ありがとうございました。

投稿2021/01/24 10:03

ponyo877

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問