如何通过 API 向 Google Drive 添加/创建/插入文件?

Posted

技术标签:

【中文标题】如何通过 API 向 Google Drive 添加/创建/插入文件?【英文标题】:How do I add/create/insert files to Google Drive through the API? 【发布时间】:2012-05-06 06:06:02 【问题描述】:

需要有关通过 api 将文件插入谷歌驱动器的帮助。为此目的的api文档并没有明确说明如何通过http post请求发送文件的实际正文。

【问题讨论】:

您使用什么语言工作?能否添加相关 API 文档的链接? 感谢您的回答。我指的链接是developers.google.com/drive/v1/reference/files/insert。 您使用什么语言?我们有几个例子。 您所指的页面包含许多编程语言的示例,这些示例解释了如何上传文件的正文。您是否正在寻找该协议的示例? 【参考方案1】:

documentation on insert operations 已经包含多种编程语言的示例,这里是如何使用基于 HTTP 的 Google Drive API 协议来实现的。

首先,将新文件元数据发布到云端硬盘端点。它必须采用File resource JSON object 的形式:

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 /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>

你已经完成了:)

还有一种方法可以在单个 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 编码传递。

最后还有一个resumable upload protocol,方便上传大文件、提供暂停/恢复功能和/或上传互联网连接不稳定的文件。

PS:大部分内容现在在Drive's file upload documentation 中进行了描述。

【讨论】:

谢谢尼古拉斯。您的解决方案帮助我了解了情况。实际上没有提到将文件内容发送到下载 url 的第二部分。但是现在我面临一个新问题,那就是当我尝试发布文件元数据时,我收到一条错误消息,提示“经过身份验证的用户尚未安装带有客户端 ID 的应用程序”。你能帮我解决这个问题吗? Niranja > 在 Google Drive 的世界里,Google Drive 应用程序只有在用户安装了应用程序的情况下才能访问用户的 Drive(通过 OAuth 2 流程是不够的)。要进行开发,您必须创建一个启用驱动器的 Chrome 网上应用店列表(请参阅developers.google.com/drive/listing)并安装它。 哦,我错过了。再次感谢。实际上我认为它类似于我们在创建 Facebook 应用程序时遵循的程序,并且没有在文档中阅读更多相关信息。 嗨尼古拉斯。您能告诉我测试我们的应用需要支付注册费吗? 对于测试,您不必公开发布您的应用程序,您应该将其发布到受信任的测试人员组(底部有一个按钮)。可以试试吗?【参考方案2】:

感谢您的解释!这让我花了好几个小时在蹩脚的谷歌 SDK 文档上兜圈子(对不起,我不得不吐槽)。

这是我创建的一个函数,它将更新一个文本文件(如您所见,我正在更新 html):

  function gd_updateFile(fileId, folderId, text, callback) 

    const boundary = '-------314159265358979323846';
    const delimiter = "\r\n--" + boundary + "\r\n";
    const close_delim = "\r\n--" + boundary + "--";

    var contentType = "text/html";
    var metadata = 'mimeType': contentType,;

    var multipartRequestBody =
        delimiter +  'Content-Type: application/json\r\n\r\n' +
        JSON.stringify(metadata) +
        delimiter + 'Content-Type: ' + contentType + '\r\n' + '\r\n' +
        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,
    );
  

这是 google 示例的混搭(使用上传的二进制文件),以及上面@Nivco 的精彩解释。

【讨论】:

【参考方案3】:

4 年后,这仍然很难弄清楚。我接受了@user1158023 的回答来支持上传图片。 我正在使用 API v3 和 superagent.js 来帮助我(因为 gapi.client.request 正在将请求发送到 content.googleapis.com!?)。希望有人会觉得这很有用。

function gd_uploadFile(name, contentType, data, callback) 
    const boundary = '-------314159265358979323846';
    const delimiter = "\r\n--" + boundary + "\r\n";
    const close_delim = "\r\n--" + boundary + "--";

    contentType = contentType || "text/html";
    var metadata = 
        name: name,
        'mimeType': contentType
    ;

    var multipartRequestBody =
        delimiter +  'Content-Type: application/json\r\n\r\n' +
        JSON.stringify(metadata) +
        delimiter +
        'Content-Type: ' + contentType + '\r\n';

    //Transfer images as base64 string.
    if (contentType.indexOf('image/') === 0) 
        var pos = data.indexOf('base64,');
        multipartRequestBody += 'Content-Transfer-Encoding: base64\r\n' + '\r\n' +
            data.slice(pos < 0 ? 0 : (pos + 'base64,'.length));
     else 
        multipartRequestBody +=  + '\r\n' + 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);
    
;

index.html

...
<form>
    <span>Upload: </span><input id="file" type="file" name="myFile">
</form>
...

【讨论】:

这救了我!非常感谢楼主!!是否可以在元数据中指定应上传到的文件夹? 哦,我很快就谈过了,我只需要添加到 metadata 对象 parents: ['0B5IwavgVGMN9ekR2dEhuaUxkZTA'] ,其中该字符串是我想要上传到的文件夹的 ID。再次感谢@Munawwar! 我有相同的代码,但我没有使用 input type="file" 我使用了 url 以及如何使用 url 上传文件到谷歌驱动器中上传?【参考方案4】:

我希望有更好的 drive 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 = "\r\n--" + boundary + "\r\n";
  const close_delim = "\r\n--" + boundary + "--";

  var metadata =  
      description : 'savefile for my game',
      'mimeType': 'application/json'
  ;  

  var multipartRequestBody =
    delimiter +  'Content-Type: application/json\r\n\r\n' +
    JSON.stringify(metadata) +
    delimiter + 'Content-Type: application/json\r\n\r\n' +
    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 的整个文档对我来说开始有意义了:-)

【讨论】:

请注意,如果您使用 gapi.client.init 并指定令牌等,则不需要上述示例中的 auth_token。【参考方案5】:

Google Drive API 团队 released v3 在 2015 年底,在该版本中,insert() 更名为create(),以便更好地反映文件操作。文档也得到了改进:现在有一个 special guide devoted to uploads(简单、多部分和可恢复),它带有 Java、Python、php、C#/.NET、Ruby、javascript/Node.js 和 ios/Obj 中的示例代码-C 用于上传常规文件,另一个用于将 CSV 文件作为 Google 表格导入。

为了直接显示,下面是一个 替代 Python 解决方案(针对文档中的示例),用于不需要 @987654329 的短文件(“简单上传”) @ 班级。此 sn-p 假定您的身份验证代码在您的服务端点为 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,Drive Service native object 和 Drive Advanced Service 仍在使用 API 的 v2。

【讨论】:

以上是关于如何通过 API 向 Google Drive 添加/创建/插入文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Google 服务帐户通过 Activity API 检索 Google Drive 活动?

通过Google Drive REST API上传或创建包含内容的新文件?

通过 Google Drive API 从本地 CSV 文件创建 Google Drive 电子表格

如何从 Google Drive 上传和下载文件(使用 Rest Api v3)

Google Drive API,无法通过 JS 打开标准共享对话框(x-frame-options 错误)

通过Google Drive API上传图片/文件