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

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

【问题讨论】:

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

标签: google-api google-drive-api google-api-client


【解决方案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 objectDrive Advanced Service 仍在使用 API 的 v2。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-22
      • 2012-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多