使用 javascript 进行 Google Drive 可恢复上传
我正在尝试使用 Google API 将文件上传到 Google 云端硬盘JavaScript 客户端库 和可恢复上传类型.
I'm trying to upload files to Google Drive using Google APIs Client Library for JavaScript and resumable upload type.
我成功验证并获取了上传 URI,但在发送实际数据时遇到了问题.如果文件仅包含 ASCII 字符,则文件会成功发送到云端硬盘,但如果是特殊字符 (åäö) 或二进制文件(例如 PNG),则文件会损坏.我的猜测是,在进程的某个地方,文件在客户端被编码为 unicode.
I authenticate and get the upload URI successfully, but I ran into problems while sending the actual data. If the file contains only ASCII characters, the file is sent successfully to Drive, but in case of special characters (åäö) or binary file (such as PNG) the file gets corrupted. My guess would be that somewhere in the process the file is encoded to unicode in client side.
如果我使用btoa()"将原始数据编码为 base64 并将标头Content-Encoding: base64"添加到数据发送请求中,则文件上传正常.然而,使用这种方法会增加 33% 的开销,这在计划上传的文件大小为 100MB 到 1GB 时是相当大的.
If I use "btoa()" to encode the raw data to base64 and add header "Content-Encoding: base64" to the data sending request, the file uploads fine. Using this method however increases the overhead for 33%, which is quite a lot when the planned upload size of files is 100MB to 1GB.
以下是一些代码示例:
获取可续传的上传 URI:
Getting the resumable upload 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中有类似问题没有答案.
Am I missing something? Is it possible to upload file in binary stream? I am new to uploading files in HTML and Javascript and I haven't found any examples using Google Javascript library with resumable upload. There is similar question in SO with no answers.
推荐答案
Blob 类型是 XMLHttpRequest
实现的热门话题,但它们并不真正成熟.我建议您坚持使用 base64 编码.Google 的 JavaScript 客户端库不支持可恢复上传,因为客户端浏览器应用不太可能将非常大的文件直接上传到 Google 云端硬盘.
Blob types are a hot topic for XMLHttpRequest
implementations and they are not truly mature. I'd recommend you to stick with base64 encoding. Google's JavaScript client lib doesn't support resumable uploads because it's very unlikely that a client side browser app uploads very large files directly to Google Drive.
相关文章