昨日以降に壊れたバイナリファイルのアップロード、回避策?

3
Paul 2020-03-03 19:56.

更新:問題を作成しました:https://issuetracker.google.com/issues/150675170

私のウェブアプリは長い間うまく機能していましたが、アップロードされたPDFファイルが突然破損しました。以下は、問題を再現するために使用できる小さな縮小例です。

アップロードされたファイルの内容を見ると、ファイルの内容がテキストとして扱われ、いくつかの文字がEF BF BD「REPLACEMENT CHARACTER」(U + FFFD)のUTF-8バイトシーケンスであるに置き換えられているように見えます。

たとえば、元のPDFファイルの最初のバイトは次のとおりです。

25 50 44 46 2D 31 2E 34 0A 25 E2 E3 CF D3 0A 31 39 | %PDF-1.4\n%âãÏÓ\n19

次のようにアップロードされました:

25 50 44 46 2D 31 2E 34 0A 25 EF BF BD EF BF BD EF BF BD EF BF BD 0A 31 39 | %PDF-1.4\n%����\n19

どこに報告すればよいかわかりません。Googleの従業員がそれを見て修正してくれることを願っています。

それまでの間、Google AppsScriptに精通している人が回避策を考えているかもしれません。

以下は小さな縮小例です-デプロイし、バイナリファイルをアップロードし、ドライブに移動し、「test」フォルダの下で見つけ、ダウンロードし、壊れていることを確認します。

HTMLテンプレート、ファイル名test_form.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>

<form id="test-form">
    <input type="file" id="test-file" name="test-file">
    <button id="submit-button" type="submit">Upload</button>
</form>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    (function () {
        'use strict';

        $('#test-form').submit(function (e) {
            e.preventDefault(); // prevent form from submitting

            google.script.run
                .withFailureHandler(fileUploadedFailure)
                .withSuccessHandler(fileUploaded)
                .uploadFilesFrame(this);
        });

        function fileUploaded(status) {
            alert(status);
        }

        function fileUploadedFailure(error) {
            alert('Failed: ' + error.message);
        }
    })();
</script>
</body>
</html>

サーバーコード、ファイル名Code.gs

var rootFolderName = "test";

function doGet(e) {
  var template = HtmlService.createTemplateFromFile('test_form');
  return template.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

function uploadFilesFrame(form) {
  try {
    var fileBlob = form['test-file'];

    var rootFolder = DriveApp.getFoldersByName(rootFolderName);
    if (rootFolder.hasNext()) {
      rootFolder = rootFolder.next();
    } else {
      rootFolder = DriveApp.createFolder(rootFolderName);
    }

    var file = rootFolder.createFile(fileBlob);

    return JSON.stringify({"status": 'ok', "msg": file.getId()});
  } catch (error) {
    return JSON.stringify({"status": 'error', "data": error.stack});
  }
}

2 answers

3
Paul 2020-03-04 03:56.

1つの回避策:base64-クライアント側でエンコードしてから、base64-サーバーでデコードします。その後、内容は台無しにされていません。次に例を示します。

HTMLテンプレート、ファイル名test_form.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>

<form id="test-form">
    <input type="file" id="test-file" name="test-file">
    <input type="hidden" id="test-file2" name="test-file2">
    <input type="hidden" id="test-file-name" name="test-file-name">
    <button id="submit-button" type="submit">Upload</button>
</form>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    (function () {
        'use strict';

        $('#test-form').submit(function (e) { var thisForm = this; e.preventDefault(); // prevent form from submitting var reader = new FileReader(); reader.onload = function (event) { var result = event.target.result; var base64 = result.substr(result.indexOf(',') + 1); $('#test-file2').val(base64);

                var filename = $('#test-file').val().split('\\').pop(); $('#test-file-name').val(filename);

                $('#test-file').prop('disabled', true);

                google.script.run
                    .withFailureHandler(fileUploadedFailure)
                    .withSuccessHandler(fileUploaded)
                    .uploadFilesFrame(thisForm);
            };
            reader.onerror = function (event) {
                alert("ERROR: " + event.target.error.code);
            };
            reader.readAsDataURL(document.getElementById('test-file').files[0]);
        });

        function fileUploaded(status) {
            alert(status);
        }

        function fileUploadedFailure(error) {
            alert('Failed: ' + error.message);
        }
    })();
</script>
</body>
</html>

サーバーコード、ファイル名Code.gs

var rootFolderName = "test";

function doGet(e) {
  var template = HtmlService.createTemplateFromFile('test_form');
  return template.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

function uploadFilesFrame(form) {
  try {
    var fileBlob = Utilities.newBlob(Utilities.base64Decode(form['test-file2']), 'application/octet-stream', form['test-file-name']);

    var rootFolder = DriveApp.getFoldersByName(rootFolderName);
    if (rootFolder.hasNext()) {
      rootFolder = rootFolder.next();
    } else {
      rootFolder = DriveApp.createFolder(rootFolderName);
    }

    var file = rootFolder.createFile(fileBlob);

    return JSON.stringify({"status": 'ok', "msg": file.getId()});
  } catch (error) {
    return JSON.stringify({"status": 'error', "data": error.stack});
  }
}
0
Cooper 2020-03-04 03:58.

送信のデフォルトの動作を防ぐため、この方法で試してみてはどうでしょうか。

あなたが私よりもそれについてもっと知っていると思うので、私は実際に今あなたにこれを言うのをためらっています。しかし、役立つように、そしておそらく愚かに見えるようにするために、私はあなたがそれをこのように試すことを提案します。

<!DOCTYPE html>
<html>
<head>
</head>
<body>

<form>
    <input type="file" id="test-file" name="test-file">
    <input type="button" value="Submit" onClick="this.parentNode" />
</form>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    function uploadFile(form) {
      google.script.run
      .withFailureHandler(fileUploadedFailure)
      .withSuccessHandler(fileUploaded)
      .uploadFilesFrame(form);
    }
    function fileUploaded(status) {
      alert(status);
    }
    function fileUploadedFailure(error) {
       alert('Failed: ' + error.message);
     }

</script>
</body>
</html>

Related questions

MORE COOL STUFF

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

ねえNFL、ジョーバロウとカイラーマレーは女性の権利をサポートするために少しの助けを使うことができます

ねえNFL、ジョーバロウとカイラーマレーは女性の権利をサポートするために少しの助けを使うことができます

ジョー・バロウロー対ウェイド事件の転覆に対応するNFLは、言葉を言わないことで、腹立たしいが予測可能なPRの結果でした。

別の日、別のヒンジのないLIV記者会見

別の日、別のヒンジのないLIV記者会見

(lから)パット・ペレス、ブルックス・ケプカ、パトリック・リードサウジアラビアのLIVゴルフリーグのさらに別の信じられないほどの記者会見で、スポーツのファンはブルックス・ケプカからでたらめな吐き気と質問回避の驚異的なマスタークラスを受けました。パトリックリード、ブライソンデシャンボー、パットペレス、最近のPGAツアーの脱北者。

ミズ・マーベルの家族の帰郷は悪役よりも激しく打撃を与える

ミズ・マーベルの家族の帰郷は悪役よりも激しく打撃を与える

レッドダガーとマーベルさんがチームを組んでいます。

6億7500万ドルのビットコインローンのデフォルト後にすべての資産を清算するように命じられたスリーアローズキャピタル

6億7500万ドルのビットコインローンのデフォルト後にすべての資産を清算するように命じられたスリーアローズキャピタル

暗号業界最大の沈没船の1つであるスリーアローズキャピタルは、ついにその悲惨さから解放されています。火曜日に、不良債権ヘッジファンドは、債権者からの返済を要求する訴訟の高まりに応えて、バージンアイランド裁判所によって清算を命じられました彼らが3ACに行ったローン。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

Suffragettes Indicam #3: Junho

Suffragettes Indicam #3: Junho

Mais um mês se findando — e metade do ano de 2022 já passou. Sabe o que isso significa? Não, não é hora de verificar se você está cumprindo com suas resoluções de Ano Novo.

多元宇宙—Junø

多元宇宙—Junø

チェーン間アカウントがJunoに登場します。異なるブロックチェーン間でスマートコントラクトの構成可能性と真の相互運用性を提供します。

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

#brand【ベター・コール・ソール!アメリカのテレビシリーズ「ブレイキング・バッド」に最高のビジネス例が隠されている】・・・ルールクリエイティブ

1.ドラマを見た後、起業する考えはありますか?あなたのビジネスはボトルネックに遭遇しましたか?方向性がなくてわからない場合は、ドラマを追いかけて行くことを心からお勧めします。(?)ブラフではなく、最も完璧なビジネス例を隠すドラマがあります。2.ブレイキング・バッドとその弁護士ドラマ「ブレイキング・バッド」を見た友人たちは、演劇の中で、穏やかな表情で、弁護士のソウル・グッドマンに深く感銘を受けなければなりません。口を開けて、感覚の弱い傭兵の性格を持っています。道徳の面で、サル・グッドマンは無意識のうちに劇に欠かせない役割を果たし、彼自身のシリーズ「絶望的な弁護士」(ベター・コール・ソール)を生み出しました。ウェントウのテキストとビデオは、劇中のソウル・グッドマンのテレビコマーシャルです。製品(サービス)、競争戦略、市場ポジショニング、ブランド名、ターゲット顧客グループ、コミュニケーション軸から広告まで、サル・グッドマンの役割のビジネス設定は、「最低」と見なすことができる超超超超超超完全です。ブランドコミュニケーションのコスト」「変化」のモデル。なぜ?私の分析をご覧ください。3.ソウル・グッドマンの「事業戦略」1.基本情報ブランド名:Saul Goodman製品:法律相談サービス対象顧客:麻薬中毒、飲酒運転、事故など。法律知識の欠如は、一般的に公立弁護士にしか余裕がなく、真面目な弁護士も「特別な法律を持つ消費者」を避けます。恐れてはいけない「​​ニーズ」。コミュニケーションの主軸:この国のすべての男性、女性、子供は有罪判決を受けるまで無実だと思います。地域:アルバカーキ市スローガン:Thrallに電話したほうがいいです!(ベター・コール・ソール)広告:2つの可能性のある犯罪状況をシミュレートします+サウルの主張+サウルのスローガン2をより適切に呼び出します。

メインネットガイド— Arbitrum Odyssey Week 2

メインネットガイド— Arbitrum Odyssey Week 2

最新のアップデートを受け取るために私たちに従ってください。ニュースレター:https://www。

Language