AndroidのWebView.loadDataにがっつりはまったのでメモ


ここ2、3日間Androidのwebviewにはまり続けていたので忘れないうちにメモ。

Androidのアプリ内のwebviewのdebugは簡単にできないのでweinre(JSをwebページに仕込んでその結果をサーバーに送りデバッガのようにブラウザで確認できるツール)を使ったり、androidのlogcatを使ったりはするのですが、それでも謎の現象に遭遇しました。

今回はandroidのwebview(デフォルトのブラウザを内部的に使用している)から前回の記事で書いたxhr2を使ったり、webviewがデータとして受け取ったHTMLをloadDataという仕組みでレンダリングしたりしていたので、ちょっと通常とは違う使い方だった訳で、色々つまずきながら解決していきました。

ちなみに、iPhoneもデバッグ事情はandroidと変わらないのですが、大体JS等がPCで動いていればきちんと動いてくれるので問題無しでした。

1. loadDataで読み込んだHTMLの中のinline scriptタグの中に”//”によるコメントがあると動かなくなる

Android2系も4系もwebviewのloadDataにはhtmlをURIEncodeした文字列をデータとして渡すのですが、¥n¥rなどの改行コードがブラウザにきちんと認識されていないせいか一行として解釈され、//以降全てのhtmlコンテンツがコメントアウトされてしまうという衝撃的な現象に見舞われました。私はそのコメント入りのscriptタグを一番下に配置していたため、描画はされているのに何故かJSのalertすらも機能しない状態になり長時間調査するはめに。。
まさかコメントが影響していたとは思いませんでした!/*コメント*/形式なら大丈夫です。

2. loadDataで読み込んだHTMLのimgタグのsrcにパラメータがつくと動かなくなる

これは調べてみると、loadDataのバグの様子。imgタグのsrc=”../img/xxx.png?001″のように?や#等追加すると、webview全体が死ぬという現象。Android2系も4系もw
もしかすると仕様なのか、訳がわからない。恐るべしloadData。。

3. loadDataで読み込んだHTMLの中に%があると動かない

Android 2系のみの現象です。loadDataに渡すHTMLの中に%って文字があると死にます。
例えば、width: 100%; なんてよく使うスタイルですが、%がエンコード文字として解釈されてしまうのか動かなくなりました。%をURIEncodeすると%25なので、それをdataで渡せば良いのかなと思ってやってみたけどダメだった気がします。%など使うスタイルはCSSに外出しして回避。

4. loaddataからのオリジンはnullになる

xhr2を使用する場合のサーバー側での注意点です。loadDataを使用したHTMLからxhrでクロスドメインリクエスト送ると、request headerのoriginがnullになります(Android 2系も4系も)。
サーバー側でAccess-Control-Allow-Origin: *なら動作しますが、ドメインを絞ろうとするとwebviewのブラウザによりabort(遮断)されます。
調べてみると、webviewのload時に特殊なconfig渡すと回避できそうです(試していませんが)。

いや〜噂には聞いていましたがandroid恐るべしですわ。