Google APIs Client Library for JavaScriptとresumable upload typeを使用して、ファイルを Google ドライブにアップロードしようとしています。
認証してアップロード URI を正常に取得しましたが、実際のデータの送信中に問題が発生しました。ファイルに ASCII 文字のみが含まれている場合、ファイルはドライブに正常に送信されますが、特殊文字 (åäö) またはバイナリ ファイル (PNG など) の場合、ファイルは破損します。私の推測では、プロセスのどこかでファイルがクライアント側でユニコードにエンコードされていると思います。
「btoa()」を使用して生データを base64 にエンコードし、ヘッダー「Content-Encoding: base64」をデータ送信要求に追加すると、ファイルは正常にアップロードされます。ただし、この方法を使用するとオーバーヘッドが 33% 増加します。これは、計画されたファイルのアップロード サイズが 100MB から 1GB の場合、かなりの量になります。
以下にいくつかのコード例を示します。
再開可能なアップロード URI の取得:
// Authentication is already done
var request = gapi.client.request({
"path": DRIVE_API_PATH, // "/upload/drive/v2/files"
"method": "POST",
"params": {
"uploadType": "resumable"
},
"headers": {
"X-Upload-Content-Type": self.file.type,
//"X-Upload-Content-Length": self.file.size
// If this is uncommented, the upload fails because the file size is
// different (corrupted file). Manually setting to the corrupted file
// size doesn't give 400 Bad Request.
},
"body": {
// self.file is the file object from <input type="file">
"title": self.file.name,
"mimeType": self.file.type,
"Content-Lenght": self.file.size,
}
});
ファイル全体を一度に送信する:
// I read the file using FileReader and readAsBinaryString
// body is the reader.result (or btoa(reader.result))
// and this code is ran after the file has been read
var request = gapi.client.request({
"path": self.resumableUrl, // URI got from previous request
"method": "PUT",
"headers": {
//"Content-Encoding": "base64", // Uploading with base64 works
"Content-Type": self.file.type
},
"body": body
});
何か不足していますか?ファイルをバイナリストリームでアップロードすることはできますか? HTML と Javascript でファイルをアップロードするのは初めてで、再開可能なアップロードで Google Javascript ライブラリを使用した例は見つかりませんでした。SOには同様の質問があり、回答はありません。