我正在尝试通过将二进制文件上传到Google云端硬盘 multipart upload API v3。
这是文件内容的十六进制表示形式:
FF FE
由于某种原因,以上内容被编码为UTF-8(我认为) 当我尝试发布时,包含在多部分有效载荷中:
--BOUNDARY
Content-Type: application/json
{"name": "F.ini"}
--BOUNDARY
Content-Type: application/octet-stream
ÿþ <-- in the outbound request, this gets UTF-8 encoded
--BOUNDARY--
最终存储在服务器端的文件的十六进制表示形式:
C3 BF C3 BE
仅在发送阶段出现问题:
如果我检查从文件读取的内容的长度,我总是得到2;
无论我使用FileReader#readAsBinaryString
还是FileReader#readAsArrayBuffer
(分别产生一个长度为2的字符串和一个ArrayBuffer
为2的byteLength
)。
这是我用来生成多部分负载的最小代码:
file = picker.files[0]; // 'picker' is a file picker
reader = new FileReader();
reader.onload = function (e) {
content = e.target.result;
boundary = "BOUNDARY";
meta = '{"name": "' + file.name + '"}';
console.log(content.length); // gives 2 as expected
payload = [
"--" + boundary, "Content-Type: application/json", "", meta, "", "--" + boundary,
"Content-Type: application/octet-stream", "", content, "--" + boundary + "--"
].join("\r\n");
console.log(payload.length); // say this gives n
xhr = new XMLHttpRequest();
xhr.open("POST", "/", false);
xhr.setRequestHeader("Content-Type", "multipart/related; boundary=" + boundary);
xhr.send(payload); // this produces a request with a 'Content-Length: n+2' header
// (corresponding to the length increase due to UTF-8 encoding)
};
reader.readAsBinaryString(file);
我的问题是双重的:
; charset=utf-8
或; charset=UTF-8
附加到二进制部分的Content-Type
标头中Content-Type: multipart/related; boundary=blablabla, charset=utf-8
;
还尝试用分号替换逗号)我需要多部分API,因为AFAIU "simple" API
不允许我上传到文件夹
(它仅通过Slug
HTTP标头接受文件名作为元数据,
而在多部分情况下,JSON元数据对象也允许指定parent
文件夹ID)。
(考虑到提及这一点,是因为“简单” API可以正确处理事情
当我直接将File
(来自选择器)或ArrayBuffer
(来自FileReader#readAsArrayBuffer
)发布为XHR的有效载荷时。)
我不想使用任何第三方库,因为
为了完整起见,我尝试通过GDrive Web界面上传相同的文件,并且上传得很好。 但是,Web界面似乎可以对有效负载进行base64编码,我想避免这种情况 (因为它不必要地使有效负载膨胀,尤其是对于较大的有效负载,这是我最终的目标)。
答案 0 :(得分:1)
此修改如何?
new FormData()
创建多部分/表单数据。reader.readAsArrayBuffer(file)
代替reader.readAsBinaryString(file)
。application/octet-stream
的形式发送。file = picker.files[0]; // 'picker' is a file picker
reader = new FileReader();
reader.onload = function (e) {
var content = new Blob([file]);
var meta = {name: file.name, mimeType: file.type};
var accessToken = gapi.auth.getToken().access_token;
var payload = new FormData();
payload.append('metadata', new Blob([JSON.stringify(meta)], {type: 'application/json'}));
payload.append('file', content);
xhr = new XMLHttpRequest();
xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart');
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.onload = function() {
console.log(xhr.response);
};
xhr.send(payload);
};
reader.readAsArrayBuffer(file);
https://www.googleapis.com/auth/drive
范围。在我的环境中,我可以确认此脚本有效。但是,如果这在您的环境中不起作用,对不起。