Google Apps ScriptのV8でGoogleドライブへのフォーム経由ファイルアップロードに不具合
2020年5月時点において、Google Apps Script(GAS)のV8を有効にした状態で、HTMLファイルで用意したフォームを経由してGoogleドライブへのファイルアップロードを行おうとすると、アップロードしたファイルが破損してしまう事象が発生しています。
GASで画像ファイルをGoogleドライブにアップロードすると不具合
不具合の事象としては、Google Apps Script(GAS)で以下の3つを実現しようとすると発生します。
- GASでHTMLファイルでファイルアップロードのフォームを用意
- アップロードボタンをトリガーにGASのスクリプトを起動
- フォームで設定した画像ファイルをGoogleドライブにアップロード
下記のようなGASのコードを用意して、Googleドライブにアップロードしようとすると、Googleドライブ上で画像が開けなくなります。
doget関数で表示するフォームのHTMLファイル
GASで公開したWebアプリケーションとして読み込むフォームのHTMLファイルは以下の通りです。
<!DOCTYPE html>
<html>
<head>
<base >
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(updateUrl).processForm(formObject);
}
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = '<a href="' + url + '">ファイルリンク</a>';
}
</script>
</head>
<body>
<form id="myForm" onsubmit="handleFormSubmit(this)">
<input name="myFile" type="file" />
<input type="submit" value="Submit" />
</form>
<div id="output"></div>
</body>
</html>
ファイルをGoogleドライブにアップロードするGASコード
フォームで入力されたファイルをGoogleドライブにアップロードするGASコードはこちらです。
//フォームのSubmitボタンがクリックされた際に実行する関数
function processForm(formObject) {
//フォームに添付されたファイルをBlob形式で取得する
var formBlob = formObject.myFile;
//取得したファイルをGoogleドライブに格納する
var driveFile = DriveApp.createFile(formBlob);
//ファイルの共有リンクを有効にし、誰でも閲覧できるようにする
driveFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
//アップロードしたファイルのURL情報を取得し、返り値に設定する
var file_url = drive_file.getDownloadUrl();
return file_url;
}
フォームでSubmitボタンが押されたタイミングでprocessForm関数が実行され、Googleドライブにファイルがアップロードされます。
GAS経由でアップした画像ファイルが開けない
Googleドライブの管理画面をGUIで操作した際には発生しないのですが、GASのスクリプトで実行しようとすると、ファイルが破損してしまいます。
アップロードした画像を端末にダウンロードしても上手くファイルを開くことができない状態です。
なぜGASのフォームでアップした画像ファイルが開けない?
ネットの情報などを調べたところ、原因はGASが2020年2月に対応したChrome V8ランタイムのバグのようです。
Google Apps Script(GAS)のWebアプリケーションとしてHTMLフォームを用意し、フォーム経由でGoogle driveにファイルをアップロードするスクリプトはネット上に色々なソースがあります。
しかし、V8ランタイム対応となった2020年2月以前に書かれたものがほとんどで、V8ランタイムのバグで実行できないことは書かれていません。
テキストファイルやHTMLファイルは問題なし
ちなみにこの事象はテキストファイルでは問題が起きていません。
テキストファイルをGASで作成したページのフォームでアップロードしても、ドライブのプレビューで表示可能でした。
また、HTMLファイルなども問題なくGoogle Apps Script経由でアップロードできます。
- 画像ファイル(jpg,png)
- 音声ファイル(wav)
- 音楽ファイル(mp3)
- 動画ファイル(mp4)
などのメディアファイルが破損する事象が発生しています。
不具合回避策はGASのV8を無効にする
画像ファイルのアップロード不具合はGoogle Apps Script(GAS)のV8ランタイムを有効化した際に発生します。
そのため、不具合を回避する方法は、GASのV8モードを無効化にすることです。
V8ランタイムを無効にした状態で、GASスクリプトでGoogleドライブに画像をアップロードすると、問題なくドライブ上で画像を閲覧できます。
※Google Apps ScriptのV8ランタイム無効化の方法はこちら
ただ、GASのV8モードを無効化にすると、ES2015などのJavascriptのモダンな構文が使用できなくなります。
変数の宣言で「let」、定数の定義に「const」などの宣言文を利用していたり、アロー関数を利用している場合は、V8ランタイムを無効化すると、コードがエラーするため、注意が必要です。
まとめ・終わりに
今回、Google Apps Script(GAS)のV8ランタイムを有効にした状態で、Googleドライブへ画像ファイルをアップロードするコードを実行すると、ファイルが壊れる事象を発生します。
こちらはV8ランタイムのバグと推定されており、V8モードを無効化することで不具合は解消されます。
ただ、すでにV8ランタイムに対応したGASのコードを書いている場合に、V8を無効にするとコードが実行エラーになります。
そのためV8対応のものは残しつつ、V8無効化した状態で動くコードをコピーして準備するのがオススメです。
ディスカッション
コメント一覧
まだ、コメントがありません