使用Google Drive API v3(JavaScript)创建文件

26
我想使用Google Drive API v3创建一个带有内容的文件。我已通过OAuth进行了身份验证,并已加载Drive API。像下面这样的语句可以工作(但是生成没有内容的文件):

我希望使用Google Drive API v3创建一个包含内容的文件。我已经通过OAuth进行了身份验证,并且已经加载了Drive API。以下类似的语句可以工作(但是会生成没有内容的文件):

gapi.client.drive.files.create({
    "name": "settings",
}).execute();

很遗憾,我无法想出如何创建具有内容的文件。我找不到使用Drive API v3的JavaScript示例。我需要传递一些特殊参数吗?

为了简单起见,假设我有一个JSON格式的字符串,例如'{"name":"test"}',它应该是创建文件的内容。


请查阅这份文档,我知道它是针对v2版本的,但是流程非常相似。您需要将URL中的版本更改为v3,并根据v3版本调整参数(例如,使用'name'代替'title')。https://developers.google.com/drive/v2/reference/files/insert#examples - Gerardo
谢谢提供链接,但我认为这有点违背使用库的精神(至少在v3中是这样):在其他情况下,我不必自己构建请求。在这里,我必须选择像我想要它成为“POST”请求这样的东西,并且必须将事物连接成由边界分隔的长字符串。我认为v3的重点是避免这些事情,我猜应该有另一种方法来做到这一点。 - Geminus
看看谷歌的一些开发人员编写的upload.js。我有一个修改过的版本适用于Drive v3 API,在这里 - Paul
5个回答

27

很遗憾,我没有找到仅使用谷歌驱动器API的答案,而是按照Gerardo的评论使用了谷歌请求API。以下是一个将文件上传到谷歌驱动器的函数。

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

  const contentType = 'application/json';

  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\r\n' +
        data +
        close_delim;

    var request = gapi.client.request({
        'path': '/upload/drive/v3/files',
        'method': 'POST',
        'params': {'uploadType': 'multipart'},
        'headers': {
          'Content-Type': 'multipart/related; boundary="' + boundary + '"'
        },
        'body': multipartRequestBody});
    if (!callback) {
      callback = function(file) {
        console.log(file)
      };
    }
    request.execute(callback);
}

15
如果您发现了如何通过 gapi.client.drive 实现此操作,我很想知道。 - David Given
1
谢谢你。我都快疯了。 - Daniel Waltrip
我有一个文件在我的文件夹里,想通过URL上传它,应该怎么做? - user5682261
1
我该如何获取此文件的内容? - vistur
@DavidGiven发布了一个使用gapi.client.drive的解决方案。 - Aurovrata
1
我知道这个答案已经有几年了,但我想补充一下,这对我很有效。非常感谢!请注意,您也可以通过这种方式上传HTML(它会转换为Google文档)。 - Brennan Moore

12

这里是使用gapi.client.drive的解决方案,

var parentId = '';//some parentId of a folder under which to create the new folder
var fileMetadata = {
  'name' : 'New Folder',
  'mimeType' : 'application/vnd.google-apps.folder',
  'parents': [parentId]
};
gapi.client.drive.files.create({
  resource: fileMetadata,
}).then(function(response) {
  switch(response.status){
    case 200:
      var file = response.result;
      console.log('Created Folder Id: ', file.id);
      break;
    default:
      console.log('Error creating the folder, '+response);
      break;
    }
});

你需要连接/授权其中一个以下范围,请参考 此链接

https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file

编辑:通过将 mimeTypeapplication/vnd.google-apps.folder 更改为受支持的Google MIME类型之一,可以创建Google文件(doc、sheet等)但是,目前不可能上传任何内容到创建的文件中。

要上传文件,请使用由@Geminus提供的解决方案。请注意,您可以上传文本文件或csv文件,并将其内容类型分别设置为Google Doc或Google Sheets,Google将尝试将其转换。 我已经测试过了,将文本转换成Doc是可行的。


2
这将创建一个文件夹,而不是一个文件。 - David Given
这实际上创建了一个文件夹,我很快会发布有关文件的解决方案。 - Aurovrata
@DavidGiven,我刚刚编辑了我的答案,你可以创建文档/表格或任何其他支持的文件类型,但是你不能使用gapi.client.drive.files.create来上传内容。 - Aurovrata
我没有编辑你的答案。我编辑了我的上面的评论(因为我误读了你的代码,评论是错误的)。 - David Given
啊,是啊!英语真是一种愚蠢的语言,不是吗?无论如何,我很感激你的帮助;我仍然想要一个实际的解决方案... - David Given
显示剩余2条评论

12

使用 gapi.client.drive,无法上传文件内容。您只能上传元数据。

建议直接使用 Google REST API 进行操作。该解决方案使用 FormData 对象构建多部分表单主体,从而简化实现,并使用 gapi.auth.getToken() 获取所需的访问令牌。该解决方案还适用于 Google 共享驱动器

var fileContent = "sample text"; // fileContent can be text, or an Uint8Array, etc.
var file = new Blob([fileContent], {type: "text/plain"});
var metadata = {
    "name": "yourFilename",
    "mimeType": "text/plain",
    "parents": ["folder id or 'root'"], // Google Drive folder id
};

var accessToken = gapi.auth.getToken().access_token;
var form = new FormData();
form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));
form.append('file', file);

fetch("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&supportsAllDrives=true", {
    method: 'POST',
    headers: new Headers({ 'Authorization': 'Bearer ' + accessToken }),
    body: form,
}).then((res) => {
    return res.json();
}).then(function(val) {
    console.log(val);
});

我来晚了,但是你有关于gapi无法上传文件内容的来源吗?我看了文档感到困惑。@mario-varchmin - bouffelec
@bouffelec 我只保留可运行的代码,而不是不能运行的代码。我并不是说使用gapi无法上传,事实上,我的建议解决方案就是使用gapi。我的意思是,在撰写本文时,使用Google API Client Library for JavaScript无法实现此功能,这也是Geminus遇到问题的原因。 - Mario Varchmin

-1

这在使用v3版本时运行良好:

        var fileMetadata = {
            'name' : 'MaxBarrass',
            'mimeType' : 'application/vnd.google-apps.folder'
        };

        gapi.client.drive.files.create({
            resource: fileMetadata,
            fields: 'id'
        }).execute(function(resp, raw_resp) {
            console.log('Folder Id: ', resp.id);
        });

3
似乎是用于创建文件夹,而不是文件。 - ADyson
是的,你可以用它来创建文件夹... 因为在 "gapi.client.drive.files.create" 中确实有 "files.create",最终都是节点,它们更像是文件而不是文件夹... - Max Barrass
2
我明白,但问题明确要求关于创建文件的内容。因此很难理解为什么展示创建文件夹的示例会有用。 - ADyson

-1
/*  Now to create a new file */ 
function insertNewFile(folderId) 
{   
    var content = " ";  
    var FolderId = ""; 
    var contentArray = new Array(content.length);
    for (var i = 0; i < contentArray.length; i++) 
    {
        contentArray[i] = content.charCodeAt(i);
    }
    var byteArray = new Uint8Array(contentArray);
    var blob = new Blob([byteArray], {type: 'text/plain'});     
    insertFile(blob, fileInserted, folderId); 
} 
function fileInserted(d) 
{   
    setPercent("100");   
    var FI = FolderId;  
    if(FI !== myRootFolderId)
    {           
        insertFileIntoFolder(FI, d.id);         
        removeFileFromFolder(d.parents[0].id,d.id);     
    }   
    openFile(d.id); 
} 
function insertFileIntoFolder(folderId, fileId) 
{   
    var body = {'id': folderId};   
    var request = gapi.client.drive.parents.insert({
        'fileId': fileId,
        'resource': body   });   
    request.execute(function(resp) { }); 
 } 

来源: https://gist.github.com/mkaminsky11/8624150


2
你错过了 insertFile(),它实际上是在工作;这与 @Geminus 上面的答案相同,使用显式的 post 来上传数据。 - David Given

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接