【问题标题】:Google Drive API and file uploads from the browser从浏览器上传 Google Drive API 和文件
【发布时间】:2018-12-18 19:01:26
【问题描述】:

我正在尝试使用 Google Drive api 上传文件,并且我的元数据正确,并且我想确保实际的文件内容在那里。我有一个简单的页面设置,如下所示:

<div id="upload">
  <h6>File Upload Operations</h6>
  <input type="file" placeholder='file' name='fileToUpload'>
  <button id='uploadFile'>Upload File</button>
</div>

我有一个 javascript 设置,其中提示用户首先登录,然后他们可以上传文件。代码如下:(目前只上传文件元数据....)

let uploadButton = document.getElementById('uploadFile');
uploadButton.onclick = uploadFile;
const uploadFile = () => {
    let ftu = document.getElementsByName('fileToUpload')[0].files[0];
    console.dir(ftu);
    gapi.client.drive.files.create({
        'content-type': 'application/json;charset=utf-8',
        uploadType: 'multipart',
        name: ftu.name,
        mimeType: ftu.type,
        fields: 'id, name, kind'
    }).then(response => {
        console.dir(response);
        console.log(`File: ${ftu.name} with MimeType of: ${ftu.type}`);
        //Need code to upload the file contents......
    });
};

首先,我更熟悉后端,所以从&lt;input type='file'&gt; 标签中获取文件对我来说有点模糊。从好的方面来说,元数据就在那里。如何将文件内容上传到 api?

【问题讨论】:

    标签: javascript google-api google-drive-api


    【解决方案1】:

    因此,根据我在三天的搜索中找到的一些资源,该文件根本无法通过 gapi 客户端上传。它必须通过真正的 REST HTTP 调用上传。所以让我们使用fetch

    const uploadFile = () => {
        //initialize file data from the dom
        let ftu = document.getElementsByName('fileToUpload')[0].files[0];
        let file = new Blob([ftu]); 
        //this is to ensure the file is in a format that can be understood by the API
    
        gapi.client.drive.files.create({
            'content-type': 'application/json',
            uploadType: 'multipart',
            name: ftu.name,
            mimeType: ftu.type,
            fields: 'id, name, kind, size'
        }).then(apiResponse => {
            fetch(`https://www.googleapis.com/upload/drive/v3/files/${response.result.id}`, {
             method: 'PATCH',
             headers: new Headers({
                 'Authorization': `Bearer ${gapi.client.getToken().access_token}`,
                  'Content-Type': ftu.type
             }),
             body: file
           }).then(res => console.log(res));
    
    }
    

    授权头是通过调用gapi.client.getToken().access_token函数分配的,基本上这会从gapi调用的响应中获取空对象并调用fetch api来上传文件的实际位!

    【讨论】:

      【解决方案2】:

      在您的情况下,当您使用 gapi.client.drive.files.create() 上传文件时,会创建包含已上传元数据的空文件。如果我的理解是正确的,这个解决方法怎么样?我和你经历过同样的情况。当时,我使用了这种解决方法。

      修改点:

      • 使用 gapi 检索访问令牌。
      • 文件是使用 XMLHttpRequest 上传的。

      修改脚本:

      请修改uploadFile()中的脚本。

      let ftu = document.getElementsByName('fileToUpload')[0].files[0];
      var metadata = {
          'name': ftu.name,
          'mimeType': ftu.type,
      };
      var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
      var form = new FormData();
      form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
      form.append('file', ftu);
      
      var xhr = new XMLHttpRequest();
      xhr.open('post', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name,kind');
      xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
      xhr.responseType = 'json';
      xhr.onload = () => {
          console.log(xhr.response);
      };
      xhr.send(form);
      

      注意:

      • 在此修改后的脚本中,假设在 API 控制台启用了 Drive API,并且访问令牌可用于上传文件。
      • 关于字段,您使用的是id,name,kind。所以这个示例也使用了它们。

      参考:

      如果我误解了您的问题或此解决方法对您的情况没有用处,我很抱歉。

      编辑:

      当你想使用fetch时,这个示例脚本怎么样?

      let ftu = document.getElementsByName('fileToUpload')[0].files[0];
      var metadata = {
          'name': ftu.name,
          'mimeType': ftu.type,
      };
      var accessToken = gapi.auth.getToken().access_token; // Here gapi is used for retrieving the access token.
      var form = new FormData();
      form.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
      form.append('file', ftu);
      
      fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,name,kind', {
        method: 'POST',
        headers: new Headers({'Authorization': 'Bearer ' + accessToken}),
        body: form
      }).then((res) => {
        return res.json();
      }).then(function(val) {
        console.log(val);
      });
      

      【讨论】:

      • 谢谢,我选择了类似的东西。我会发布作为答案。
      • @Chris Rutherford 感谢您的回复。如果我的回答对您的情况没有帮助,我深表歉意。
      • 这并不是说它没有用,我只是觉得使用 fetch 可能是一个更好的选择。 XHR 很旧,如果使用不当容易出错。 Fetch 是新的标准。就这样。谢谢@tanaike
      • @Chris Rutherford 感谢您的回复。我能理解。我很抱歉我的技能不好。
      • @Chris Rutherford 我使用fetch 添加了一个示例脚本。你能确认一下吗?在您的脚本中,上传文件时会使用两次 Drive API。该脚本可以通过一个 API 调用上传文件。如果这对您的情况有帮助,我很高兴。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-13
      • 2017-10-10
      • 2020-03-10
      • 2023-03-03
      • 1970-01-01
      相关资源
      最近更新 更多