Monacaチームの小田川です。
これまでは、Qiitaに月一くらいのペースで投稿していましたが、今回からアシアルブログに投稿することになりました。今回は、WKWebView環境で外部サーバからダウンロードした画像を画面に表示するテストをしてみたいと思います。

file:// スキーム
Monacaで利用しているCordovaでは、外部リソースにアクセスする際に、file:// スキームが使用されます。WKWebViewでは、セキュリティー制限により、file:// スキームでリソースにアクセスすることができません。
Monacaプロジェクトの www フォルダ内に配置されているリソースの場合は、Monacaから提供されている Custom Schemeプラグイン を使用することで対応することができますが、外部サーバからアプリ内にダウンロードした画像ファイルなどには、アクセスすることができません。
ダウンロードした画像を表示する
外部サーバからアプリ内にダウンロードした画像ファイルなどにアクセスする場合は、blob データを利用します。
ダウンロードする画像ファイルをblobデータとしてダウンロードした場合は、window.URL.createObjectURL から取得できるURLを使用することで、画像にアクセスすることができます。
<script>
  function downloadFile1() {
    var xmlHttpRequest = new XMLHttpRequest();
    xmlHttpRequest.open("GET", "https://cordova.apache.org/static/img/cordova_bot.png", true);
    xmlHttpRequest.responseType = "blob";
    xmlHttpRequest.onload = function(event) {
      var blob = xmlHttpRequest.response;
      if (blob) {
        // blobデータのURLを取得
        var url = window.URL.createObjectURL(blob);
        // 画像を表示
        document.getElementById('img1').src = url;
      } else {
        console.log('error');
      }
    };
    // ファイルをダウンロード
    xmlHttpRequest.send();
  }
</script>
<body>
  <input type="button" value="downloadFile1" onclick="downloadFile1()" />
  <img id="img1" />
</body>
blobデータとして画像を表示するため、Content-Security-Policy に blob: を追加する必要があります。
<meta http-equiv="Content-Security-Policy" content="default-src * blob: data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
WKWebView用のカスタムビルドデバッガーで window.URL.createObjectURL を使用した場合は、下記のようなURLが取得されます。
blob:monaca-debugger://アプリID.monaca.io/99e8aba5-f365-4b3c-b17a-bac2ec802dab
デバッグビルドしたアプリで window.URL.createObjectURL を使用した場合は、下記のようなURLが取得されます。
blob:null/c1212065-cb51-4d73-911b-e1b2e9ccb559
WKWbViewでは、file:// スキームが null に変換されます。
上記のような null が設定されたURLでも画像が表示されますが、Custom Schemeプラグインを有効にした場合は、下記のようなURLが取得されます。
blob:monaca-app://monaca.io/c1212065-cb51-4d73-911b-e1b2e9ccb559
ダウンロードしてファイル保存した画像を表示する その1
ダウンロードしてファイル保存した画像の場合も、保存した画像ファイルをblobデータとして取得することで、window.URL.createObjectURL を利用することができます。
サンプルでは、Fileプラグイン を使用しています。
Fileプラグインの cordova.file.documentsDirectory から取得できるDocumentsフォルダパスにダウンロードしたファイルを保存しています。
<script>
  function downloadFile2() {
    // ファイル保存ディレクトリに cordova.file.documentsDirectory を設定
    window.resolveLocalFileSystemURL(cordova.file.documentsDirectory, function (dirEntry) {
      var fileName = "sample.png";
      var mimeType = "image/png"
      var xmlHttpRequest = new XMLHttpRequest();
      xmlHttpRequest.open("GET", "https://cordova.apache.org/static/img/cordova_bot.png", true);
      xmlHttpRequest.responseType = 'blob';
      xmlHttpRequest.onload = function() {
        if (this.status == 200) {
          var blob = new Blob([this.response], { type: mimeType });
          // ファイルの作成
          dirEntry.getFile(fileName, { create: true, exclusive: false }, function (fileEntry) {
            fileEntry.createWriter(function (fileWriter) {
              fileWriter.onwriteend = function() {
                if (blob.type == mimeType) {
                  fileEntry.file(function (file) {
                    var reader = new FileReader();
                    reader.onloadend = function() {
                      // 読み込んだデータから blob データを作成
                      var blob = new Blob([new Uint8Array(this.result)], { type: mimeType });
                      // ファイルパスの取得
                      // file:// スキームパスのため、アクセスできません。
                      // var url = fileEntry.toURL();
                      // blobデータのURLを取得
                      var url = window.URL.createObjectURL(blob);
                      console.log("fileEntry.toURL: " + fileEntry.toURL());
                      console.log("window.URL.createObjectURL: " + window.URL.createObjectURL(blob));
                      // 画像を表示
                      document.getElementById('img1').src = url;
                    };
                    // ファイルの読み込み
                    reader.readAsArrayBuffer(file);
                  });
                }
              };
              fileWriter.onerror = function(err) {
                console.log("Failed file write: " + err.toString());
              };
              // ファイルへ書き込み
              fileWriter.write(blob);
            });
          });
        }
      };
      // ファイルをダウンロード
      xmlHttpRequest.send();
    }, function(err) {
      console.log('error: resolveLocalFileSystemURL');
    }); 
  }
</script>
<body>
  <input type="button" value="downloadFile2" onclick="downloadFile2()" />
  <img id="img1" />
</body>
画像を表示するためのURLに fileEntry.toURL() を使用した場合は、file:// スキームパスになるため、画像は表示されません。
インスペクターで確認すると、下記のようなエラーが表示されます。
Not allowed to load local resource: file:///var/mobile/Containers/Data/Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents/sample.png
Failed to load resource: The operation couldn’t be completed. Operation not permitted
ダウンロードしてファイル保存した画像を表示する その2
WKWebViewの file:// スキーム制限は、ファイルが保存されている場所に依存しています。
ダウンロードしてファイル保存した画像を表示する その1 では、ファイルの保存場所に cordova.file.documentsDirectory を指定しました。この cordova.file.documentsDirectory で取得できるパスは、アプリ内の Documents フォルダになります。Documentsフォルダの場合は、file:// スキーム制限が適用されます。
アプリ内の tmp フォルダ内のファイルの場合は、file:// スキーム制限は適用されません。そのため、tmpフォルダ内のファイルの場合は、file:// スキームのパスを使用することができます。tmpフォルダのパスは、cordova.file.tempDirectory で取得できます。
注意点として、Custom Schemeプラグインを有効にしている場合や、WKWebView用のカスタムビルドデバッガーを使用している場合は、仕様上、file:// スキーム制限が適用されるため、window.URL.createObjectURL を使用してください。
おわりに
WKWebView環境でダウンロードした画像などが表示されない場合は、一度、window.URL.createObjectURL で取得したURLやファイルの保存先を cordova.file.tempDirectory にして試してみてください。