介绍
首先让我介绍一下我要做的事情的目标。
>
之前我把一个文件分成两部分
这两个文件的大小加在一起可能超过50 MB(作为一个长期目标)。由于UrlFetchApp.fetch()对请求的大小有限制,我想单独上传它们,其中每个文件将小于50 MB,并因此合并它们。现在(尝试驱动器API),我使用小文件。
第一个文件是
640000字节
(是
256
)
524288字节
。我意识到我之前犯了一个错误,即我使用的文件大小是256的倍数,但它应该是256*1024的倍数
第二个文件是
我使用curl
分割文件,并将它们上传到我的驱动器(正常的网络上传)。
我的意图是使用谷歌应用脚本中的
谷歌驱动API
将部分文件
一个接一个地上传到谷歌驱动,以便将它们合并到一个文件中。
到目前为止我尝试了什么?
昨天,我在这里问了一个问题。我试图使用驱动器执行可恢复上传
。文件夹。插入
,用户指出无法使用驱动器。文件夹。插入下面引用的
不幸的是,在当前阶段,无法使用驱动器实现可恢复上传。文件夹。插入这似乎是谷歌方面当前的规范
我现在尝试的是使用Google Drive API
。下面是代码
function myFunction() {
var token = ScriptApp.getOAuthToken();
var f1_id = '1HkBDHV1oXXXXXXXXXXXXXXXXXXXXXXXX';
var f2_id = '1twuaKTCFTXXXXXXXXXXXXXXXXXXXX';
var putUrl = 'https://www.googleapis.com/drive/v3/files?uploadType=resumable';
var fileData = {
name : 'Merged-file-from-GAS',
file : DriveApp.getFileById(f1_id).getBlob()
}
var options = {
method : 'put',
contentType:"application/json",
headers : {
Authorization: 'Bearer ' + token,
'X-Upload-Content-Type' : 'application/octet-stream',
'Content-Type' : 'application/json; charset=UTF-8'
},
muteHttpExceptions: true,
payload : fileData
};
var response = UrlFetchApp.fetch(putUrl, options);
Logger.log(response.getResponseCode());
Logger.log(response.getAllHeaders());
}
>
我还尝试将方法更改为
patch
我在
标题中添加了
内容长度:640000
,在这种情况下,我收到一个错误,如下所示。
异常:提供无效值的属性:标头:内容长度
我试图创建一个文件使用驱动器。Files.insert(资源)
使用空白资源
。然后我尝试使用UrlFetchApp(patchUrl,选项)
更新它,同时使用变量var patchUrl='https://www.googleapis.com/upload/drive/v3/files/'fileId'?##恢复##############################################################################################################################
后果
它不会创建任何文件
下面提供了附加代码(初始代码)结果的记录器日志:
[20-05-12 21:05:37:726 IST]404.0
[20-05-12 21:05:37:736 IST]{X-Frame-Options=SAMEORIGIN,内容安全策略=帧祖先的自我,传输编码=分块,alt svc=h3-27=“:443;ma=2592000,h3-25=“:443”;ma=2592000,h3-Q050=“:443;ma=2592000,h3-Q049=“:443”;ma=2592000,h3-Q048=“:443”;ma=2592000,h3-Q046=“:443”;ma=2592000,h3=2592000,h3-Q043=:443=:443; ma=2592000;v=“46,43”,X-Content-Type-Options=nosniff,Date=Tue,2020年5月12日15:35:37 GMT,Expires=Mon,Jan 1990 00:00:00 GMT,X-XSS-Protection=1;mode=block,Content Encoding=gzip,Pragma=no cache,cache Control=no cache,no store,max age=0,必须重新验证,Vary=[Origin,X-Origin],Server=GSE,Content Type=text/html;字符集=UTF-8}
问题
>
使用应用程序脚本中的驱动API,将驱动器中的文件上传到驱动器,同时将上传类型保持为可恢复的,正确的方法是什么?
后续请求应该是什么样的?这样50MB以上的文件就可以上传到合并文件中了?
编辑1
再次尝试使用修正的文件块大小。同样的问题依然存在。
编辑2
为了理解答案中的代码,我仅使用了Tanaike代码的
/2
中的代码来理解如何检索位置
。
function understanding() {
var token = ScriptApp.getOAuthToken();
const filename = 'understanding.pdf';
const mimeType = MimeType.PDF;
const url = 'https://www.googleapis.com/drive/v3/files?uploadType=resumable';
const res1 = UrlFetchApp.fetch(url, {
method: "post",
contentType: "application/json",
payload: JSON.stringify({name: filename, mimeType: mimeType}),
headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()
}});
const location = res1.getHeaders().Location;
Logger.log(location);
}
这将创建一个文件
理解。pdf
大小0字节
。然而,Logger。日志(位置)
logsnull
。
为什么会这样?
错误就在终点。将其设置为
https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable
有效。它检索位置。
塔奈克的答案非常完美。它很优雅,甚至帮助我了解了数组。减少
功能。在我问这个问题之前,我对JavaScript知之甚少,对使用Google Drive API
几乎一无所知。
我的意图是使用谷歌应用脚本
作为语言,逐步学习可恢复上传
的整个过程。以塔奈克的代码为参考,我写了一个脚本,它不是高效的、可管理的、优雅的,而是(至少)让我一步一步地了解可恢复上传的工作原理。我没有使用循环,没有对象,甚至没有数组。
步骤1(声明必要的变量)
var fileId1 = "XXXXXXXXXXX"; //id of the first file
var fileId2 = "YYYYYYYYYYY"; //id of the second file
var filename = "merged.pdf"; //name of the final merged file
var mimeType = MimeType.PDF; //Mime type of the merged file
步骤2(启动可恢复上传)
//declare the end point
const url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable";
//Send the request
//Method to be used is Post during initiation
//No file is to be sent during initiation
//The file name and the mime type are sent
const res1 = UrlFetchApp.fetch(url, {
method: "post",
contentType: "application/json",
payload: JSON.stringify({name: filename, mimeType: mimeType}),
headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()
}});
步骤3(保存可恢复会话URI)
const location = res1.getHeaders().Location;
步骤4(a)(上传文件1)
注意:步骤4(a)和(b)可以使用循环执行。在我的例子中,我使用了两次,没有循环
var file = DriveApp.getFileById(fileId1); //get the first file
var data = file.getBlob().getBytes(); //get its contents in bytes array
//Method used is PUT not POST
//Content-Range will contain the range from starting byte to ending byte, then a slash
//and then file size
//bytes array of file's blob is put in data
var params = {
method : "put",
headers : {
'Content-Range' : `bytes 0-524287/687627`
},
payload : data,
muteHttpExceptions: true
};
//Request using Resumable session URI, and above params as parameter
var result = UrlFetchApp.fetch(location,params);
步骤4(b)(上传第二个文件)
//Almost same as Step 4 (a)
//The thing that changes is Content Range
file = DriveApp.getFileById(fileId2);
data = file.getBlob().getBytes();
params = {
method : "put",
headers : {
'Content-Range' : `bytes 524288-687626/687627`
},
payload : data,
muteHttpExceptions : true
};
result = UrlFetchApp.fetch(location, params);
现在,与其执行步骤4
n
次数,不如使用循环。
此外,此代码不会检查过程中可能发生的错误。
希望这段代码能帮助别人,尽管它更像是一个自学实验。:)
从你的问题和回答,我可以理解你的情况和目标如下。
对于这个,这个答案怎么样?
>
不幸的是,您的脚本不完整,无法实现可恢复上传。Google Drive API上的可恢复上传流程如下所示。裁判
对于上面的流程,当准备好示例脚本时,它变成如下所示。
在这种情况下,将使用Drive API。因此,请在高级谷歌服务中启用驱动器应用编程接口。这样,在API控制台就会自动启用Drive API。
示例脚本的流程如下所示。
请复制并粘贴以下脚本。并请设置文件ID。在这种情况下,请按合并顺序设置它们。请小心这个。
function myFunction() {
const fileIds = ["###", "###"]; // Please set the file IDs of the file "A" and "B" in order.
const filename = "sample.pdf";
const mimeType = MimeType.PDF;
// 1. Create an object for using at the resumable upload.
const unitSize = 262144;
const fileObj = fileIds.reduce((o, id, i, a) => {
const file = DriveApp.getFileById(id);
const size = file.getSize();
if (i != a.length - 1 && (size % unitSize != 0 || size > 52428800)) {
throw new Error("Size of each file is required to be the multiples of 262,144 bytes and less than 52,428,800 bytes.");
}
o.files.push({data: file.getBlob().getBytes(), range: `bytes ${o.size}-${o.size + size - 1}\/`, size: size.toString()});
o.size += size;
return o;
}, {size: 0, files: []});
// 2. Retrieve "location" for starting the resumable upload.
const url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable";
const res1 = UrlFetchApp.fetch(url, {
method: "post",
contentType: "application/json",
payload: JSON.stringify({name: filename, mimeType: mimeType}),
headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()
}});
const location = res1.getHeaders().Location;
// 3. Upload each file and merge them.
fileObj.files.forEach((e, i) => {
const params = {
method: "put",
headers: {"Content-Range": e.range + fileObj.size},
payload: e.data,
muteHttpExceptions: true,
};
const res = UrlFetchApp.fetch(location, params);
const status = res.getResponseCode();
if (status != 308 && status != 200) {
throw new Error(res.getContentText());
}
if (status == 200) {
console.log(res.getContentText())
}
});
// DriveApp.createFile() // This comment line is used for automatically detecting the scope of "https://www.googleapis.com/auth/drive" by the script editor. So please don't remove this line.
}
当可恢复上传完成后,可以在日志中看到以下结果。您可以在根文件夹中看到合并的文件。
{
"kind": "drive#file",
"id": "###",
"name": "sample.pdf",
"mimeType": "application/pdf"
}
我是否需要登录到google cloud来访问身份验证令牌或凭据的API
问题内容: 使用此代码,我上传文件,但该文件作为文档上传。表示我上传该文件的任何类型都将作为文档上传到Google驱动器 问题答案: 据我所知(距离我查看已经有几个月了 ) ,谷歌驱动器API 还不支持(至今?) 。解决方法是考虑安装本机google驱动器共享,然后将要上传的文件写入本地映射的共享文件夹中。然后它的谷歌驱动器问题来处理上传。
我正在用Google Apps脚本编写一个JavaScript工具来检查文档的一些属性,比如“所有链接是否有效”、“权限设置是否正确”等等。我正在使用中记录的APIhttps://developers.google.com/apps-script/reference/drive/drive-app通过ID查找文件,检查它们的权限,在GoogleDrive中找到它们,等等,但是我发现“共享驱动器”与
我尝试使用REST API将一个简单的文本作为文件上传到oneDrive。 我创造了一个象征:https://login.microsoftonline.com/ < li >授予类型客户端凭据 < li >客户端id我的客户端id < li>client_secret我的客户端机密 < Li > https://graph.microsoft.com/.default范围 Content-Typ
我使用以下JCIFS代码将文件从本地磁盘复制到共享驱动器 复制10 mb文件需要10分钟以上。而当我直接复制同一个文件时,大约需要1分钟。我尝试了3种方法来复制文件(请参阅代码的注释部分),但没有一种方法显示出任何显著的差异。 是否有任何方法可以提高JCIFS的性能?
> 我想从上到下滚动android移动应用程序页面。 我尝试了以下定义的滚动编码,并使用文本单击特定的网络元素。它工作正常。 //滚动到页面底部