需要有关通过 API 将文件插入 Google 云端硬盘的帮助。用于此目的的 api 文档没有清楚地解释如何通过 http post 请求发送文件的实际正文。
关于插入操作的文档已经包含了一系列编程语言的示例,以下是如何使用 Google Drive API 的基于 HTTP 的协议来做到这一点。
首先,将新文件元数据发布到驱动器终结点。它必须采用文件资源 JSON 对象的形式:
POST /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <OAuth 2.0 access token here>
...
{
"title": "file_name.extension",
"mimeType": "mime/type",
"description": "Stuff about the file"
}
响应正文将是新创建的文件资源的 JSON 表示形式。它将看起来像:
{
"kind": "drive#file",
"id": string,
"etag": etag,
"selfLink": string,
"title": "file_name",
"mimeType": "mime/type",
"description": "Stuff about the file"
...
"downloadUrl": string,
...
}
这是对文件条目已创建的确认。现在您需要上传内容。为此,您需要获取上述响应中 id JSON 属性给出的文件 ID,并使用 OAuth 2.0 授权请求将实际文件的内容 PUT 到上传终端节点。它应如下所示:
PUT /upload/drive/v2/files/{id}?uploadType=media HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <OAuth 2.0 access token here>
Content-Type: mime/type
<file content here>
你完了:)
还有一种方法可以使用多部分请求在 1 个单个 POST 请求中执行此操作,您可以在其中同时发布文件的元数据和内容。下面是一个示例:
POST /upload/drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer <OAuth 2.0 access token here>
Content-Type: multipart/form-data; boundary=287032381131322
...
--287032381131322
Content-Type: application/json
{
"title": "file_name.extension",
"mimeType": "mime/type",
"description": "Stuff about the file"
}
--287032381131322
Content-Type: mime/type
<file content here>
--287032381131322--
响应将包含新创建文件的元数据。您还可以在请求的子部分中使用 Content-Transfer-Encoding: base64 标头,以便能够以 Base 64 编码的方式传递文件的数据。
最后,还有一个可恢复的上传协议,可以方便地上传大文件,提供暂停/恢复功能和/或上传具有不稳定互联网连接的文件。
PS:大部分内容现在在云端硬盘的文件上传文档中都有描述。
感谢您的解释!这花了我几个小时在蹩脚的谷歌SDK文档中兜圈子(对不起,我不得不把我的咆哮出来)。
这是我制作的一个函数,它将更新文本文件(如您所见,我正在更新 html):
function gd_updateFile(fileId, folderId, text, callback) {
const boundary = '-------314159265358979323846';
const delimiter = "rn--" + boundary + "rn";
const close_delim = "rn--" + boundary + "--";
var contentType = "text/html";
var metadata = {'mimeType': contentType,};
var multipartRequestBody =
delimiter + 'Content-Type: application/jsonrnrn' +
JSON.stringify(metadata) +
delimiter + 'Content-Type: ' + contentType + 'rn' + 'rn' +
text +
close_delim;
if (!callback) { callback = function(file) { console.log("Update Complete ",file) }; }
gapi.client.request({
'path': '/upload/drive/v2/files/'+folderId+"?fileId="+fileId+"&uploadType=multipart",
'method': 'PUT',
'params': {'fileId': fileId, 'uploadType': 'multipart'},
'headers': {'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'},
'body': multipartRequestBody,
callback:callback,
});
}
这是谷歌示例的混搭(它使用上传的二进制文件),以及上面@Nivco很好的解释。
年后,这仍然很难弄清楚。我接受了@user1158023的答案来支持上传图像。我正在使用API v3和超级代理.js来帮助我(因为gapi.client.request正在向 content.googleapis.com 发送请求!?)。希望有人会发现这很有用。
function gd_uploadFile(name, contentType, data, callback) {
const boundary = '-------314159265358979323846';
const delimiter = "rn--" + boundary + "rn";
const close_delim = "rn--" + boundary + "--";
contentType = contentType || "text/html";
var metadata = {
name: name,
'mimeType': contentType
};
var multipartRequestBody =
delimiter + 'Content-Type: application/jsonrnrn' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + 'rn';
//Transfer images as base64 string.
if (contentType.indexOf('image/') === 0) {
var pos = data.indexOf('base64,');
multipartRequestBody += 'Content-Transfer-Encoding: base64rn' + 'rn' +
data.slice(pos < 0 ? 0 : (pos + 'base64,'.length));
} else {
multipartRequestBody += + 'rn' + data;
}
multipartRequestBody += close_delim;
if (!callback) { callback = function(file) { console.log("Update Complete ", file) }; }
superagent.post('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart').
set('Content-Type', 'multipart/form-data; boundary="' + boundary + '"').
set('Authorization', 'Bearer ' + gapi.auth.getToken().access_token).
send(multipartRequestBody).
end(function () {
console.log(arguments);
});
}
//On upload
$('#file')[0].onchange = function () {
var file = $('#file')[0].files[0];
if (file && file.type === 'image/jpeg') {
var reader = new FileReader();
reader.onloadend = function () {
var data = reader.result;
gd_uploadFile('img.jpg', 'image/jpeg', data, function () {
console.log(arguments);
});
}
reader.readAsDataURL(file);
}
};
索引.html
...
<form>
<span>Upload: </span><input id="file" type="file" name="myFile">
</form>
...
我担心有更好的驱动器 gapis v3 示例......我花了一些时间来弄清楚如何将新内容上传到使用
gapi.client.drive.files.create({ "name" : "savefile.txt" }).execute(function(file) { console.log("Created file " + file.name + " id: " + file.id); });
但最终我尝试了将 fileId 添加到路径并将方法更改为 PATCH 的"幸运"组合
function uploadFile(id, text)
{
var auth_token = gapi.auth.getToken().access_token;
const boundary = '-------314159265358979323846';
const delimiter = "rn--" + boundary + "rn";
const close_delim = "rn--" + boundary + "--";
var metadata = {
description : 'savefile for my game',
'mimeType': 'application/json'
};
var multipartRequestBody =
delimiter + 'Content-Type: application/jsonrnrn' +
JSON.stringify(metadata) +
delimiter + 'Content-Type: application/jsonrnrn' +
text +
close_delim;
gapi.client.request
( {
'path': '/upload/drive/v3/files/'+id,
'method': 'PATCH',
'params': {'fileId': id, 'uploadType': 'multipart'},
'headers': { 'Content-Type': 'multipart/form-data; boundary="' + boundary + '"', 'Authorization': 'Bearer ' + auth_token, },
'body': multipartRequestBody
}).execute(function(file) { console.log("Wrote to file " + file.name + " id: " + file.id); });
}
但我想现在 https://developers.google.com/drive/v3/reference/files/update 的整个文档对我来说开始有意义:-)
Google 云端硬盘 API 团队在 2015 年底发布了 v3,在该版本中,insert()
将名称更改为 create()
,以便更好地反映文件操作。文档也得到了改进:现在有一个专门用于上传(简单、多部分和可恢复)的特殊指南,其中包含 Java、Python、PHP、C#/.NET、Ruby、JavaScript/Node.js 和 iOS/Obj-C 的示例代码,用于上传常规文件,另一个用于将 CSV 文件导入为 Google 表格。
为了直截了当地显示它,下面是一个替代的 Python 解决方案(到文档中的示例),用于不需要apiclient.http.MediaFileUpload
类的短文件("简单上传")。此代码段假定您的身份验证代码在DRIVE
服务终结点且最小身份验证范围为 https://www.googleapis.com/auth/drive.file
的情况下工作。
# filenames & MIMEtypes
DST_FILENAME = 'inventory'
SRC_FILENAME = DST_FILENAME + '.csv'
SHT_MIMETYPE = 'application/vnd.google-apps.spreadsheet'
CSV_MIMETYPE = 'text/csv'
# Import CSV file to Google Drive as a Google Sheets file
METADATA = {'name': DST_FILENAME, 'mimeType': SHT_MIMETYPE}
rsp = DRIVE.files().create(body=METADATA, media_body=SRC_FILENAME).execute()
if rsp:
print('Imported %r to %r (as %s)' % (SRC_FILENAME, DST_FILENAME, rsp['mimeType']))
请注意,如果您正在编写Android应用程序,则有一个单独的Google Drive API for Android,其中包含自己的文档集。最后,如果您在 Google Apps 脚本上使用 JavaScript,则云端硬盘服务本机对象和云端硬盘高级服务仍在使用 API 的 v2。