#javascript #ajax #google-apps-script
#javascript #ajax #google-apps-script
Вопрос:
Я внедряю возобновляемую загрузку кода Kanshi Tanaike для веб-приложений, и это работает, но я не до конца понимаю AJAX и пытаюсь добавить функцию. Прямо сейчас код помещает новый файл в корневую папку пользовательского диска. Я хотел бы либо определить конкретную папку и загрузить ее напрямую, либо автоматически переместить файл из корня в нужную папку (мне также нужно собрать ссылку для скачивания). Я вижу, что функция загрузки ссылается на местоположение в заголовке ответа, но я изо всех сил пытаюсь понять, как его определить, и поскольку функция doUpload (), похоже, не обрабатывает загрузку как файловый объект, я не могу понять, как ссылаться на него после загрузки, чтобы получить URL-адрес или переместитьэто. Любая обратная связь будет чрезвычайно оценена.
$('#uploadfile').on("change", function() {
var file = this.files[0];
if (file.name != "") {
var fr = new FileReader();
fr.fileName = file.name;
fr.fileSize = file.size;
fr.fileType = file.type;
fr.onload = init;
fr.readAsArrayBuffer(file);
}
});
function init() {
$("#progress").text("Initializing.");
var fileName = this.fileName;
var fileSize = this.fileSize;
var fileType = this.fileType;
console.log({fileName: fileName, fileSize: fileSize, fileType: fileType});
var buf = this.result;
var chunkpot = getChunkpot(chunkSize, fileSize);
var uint8Array = new Uint8Array(buf);
var chunks = chunkpot.chunks.map(function(e) {
return {
data: uint8Array.slice(e.startByte, e.endByte 1),
length: e.numByte,
range: "bytes " e.startByte "-" e.endByte "/" chunkpot.total,
};
});
google.script.run.withSuccessHandler(function(at) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable");
xhr.setRequestHeader('Authorization', "Bearer " at);
xhr.setRequestHeader('Content-Type', "application/json");
xhr.send(JSON.stringify({
mimeType: fileType,
name: fileName,
}));
xhr.onload = function() {
doUpload({
location: xhr.getResponseHeader("location"),
chunks: chunks,
});
};
xhr.onerror = function() {
console.log(xhr.response);
};
}).getAt();
}
function doUpload(e) {
var chunks = e.chunks;
var location = e.location;
var cnt = 0;
var end = chunks.length;
var temp = function callback(cnt) {
var e = chunks[cnt];
var xhr = new XMLHttpRequest();
xhr.open("PUT", location, true);
xhr.setRequestHeader('Content-Range', e.range);
xhr.send(e.data);
xhr.onloadend = function() {
var status = xhr.status;
cnt = 1;
console.log("Uploading: " status " (" cnt " / " end ")");
$("#progress").text("Uploading: " Math.floor(100 * cnt / end) "%");
if (status == 308) {
callback(cnt);
} else if (status == 200) {
$("#progress").text("Done.");
} else {
$("#progress").text("Error: " xhr.response);
}
};
}(cnt);
}
Ответ №1:
Я считаю, что ваша цель и ваша текущая ситуация заключаются в следующем.
- Вы хотите загрузить файл в определенную папку.
- Вы хотите получить
webContentLink
загруженный файл. - Вы хотите достичь вышеуказанного, используя возобновляемую загрузку для веб-приложений с помощью скрипта Google Apps
- Вы уже подтвердили, что сценарий по умолчанию в репозитории работал.
Точки модификации:
- В этом случае требуется проверить возобновляемую загрузку и метод «Files: create» в Drive API.
- Чтобы загрузить файл в определенную папку, пожалуйста, добавьте идентификатор папки в тело запроса первоначального запроса.
- Чтобы вернуть значение
webContentLink
, пожалуйста, используйтеfields
значение для первоначального запроса.
Когда вышеуказанные пункты отражаются в исходном сценарии, это выглядит следующим образом.
Модифицированный сценарий:
В этом случае HTML изменяется.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<title>Resumable upload for Web Apps</title>
</head>
<body>
<form>
<input name="file" id="uploadfile" type="file">
</form>
<div id="progress"></div>
<script>
const chunkSize = 5242880;
$('#uploadfile').on("change", function() {
var file = this.files[0];
if (file.name != "") {
var fr = new FileReader();
fr.fileName = file.name;
fr.fileSize = file.size;
fr.fileType = file.type;
fr.onload = init;
fr.readAsArrayBuffer(file);
}
});
function init() {
var folderId = "###"; // Added: Please set the folder ID.
$("#progress").text("Initializing.");
var fileName = this.fileName;
var fileSize = this.fileSize;
var fileType = this.fileType;
console.log({fileName: fileName, fileSize: fileSize, fileType: fileType});
var buf = this.result;
var chunkpot = getChunkpot(chunkSize, fileSize);
var uint8Array = new Uint8Array(buf);
var chunks = chunkpot.chunks.map(function(e) {
return {
data: uint8Array.slice(e.startByte, e.endByte 1),
length: e.numByte,
range: "bytes " e.startByte "-" e.endByte "/" chunkpot.total,
};
});
google.script.run.withSuccessHandler(function(at) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumableamp;fields=*");
xhr.setRequestHeader('Authorization', "Bearer " at);
xhr.setRequestHeader('Content-Type', "application/json");
xhr.send(JSON.stringify({
mimeType: fileType,
name: fileName,
parents: [folderId] // Added
}));
xhr.onload = function() {
doUpload({
location: xhr.getResponseHeader("location"),
chunks: chunks,
});
};
xhr.onerror = function() {
console.log(xhr.response);
};
}).getAt();
}
function doUpload(e) {
var chunks = e.chunks;
var location = e.location;
var cnt = 0;
var end = chunks.length;
var temp = function callback(cnt) {
var e = chunks[cnt];
var xhr = new XMLHttpRequest();
xhr.open("PUT", location, true);
xhr.setRequestHeader('Content-Range', e.range);
xhr.send(e.data);
xhr.onloadend = function() {
var status = xhr.status;
cnt = 1;
console.log("Uploading: " status " (" cnt " / " end ")");
$("#progress").text("Uploading: " Math.floor(100 * cnt / end) "%");
if (status == 308) {
callback(cnt);
} else if (status == 200) {
var metadata = JSON.parse(xhr.response); // Added
$("#progress").text("Done. Link: " metadata.webContentLink); // Modified
} else {
$("#progress").text("Error: " xhr.response);
}
};
}(cnt);
}
function getChunkpot(chunkSize, fileSize) {
var chunkPot = {};
chunkPot.total = fileSize;
chunkPot.chunks = [];
if (fileSize > chunkSize) {
var numE = chunkSize;
var endS = function(f, n) {
var c = f % n;
if (c == 0) {
return 0;
} else {
return c;
}
}(fileSize, numE);
var repeat = Math.floor(fileSize / numE);
for (var i = 0; i <= repeat; i ) {
var startAddress = i * numE;
var c = {};
c.startByte = startAddress;
if (i < repeat) {
c.endByte = startAddress numE - 1;
c.numByte = numE;
chunkPot.chunks.push(c);
} else if (i == repeat amp;amp; endS > 0) {
c.endByte = startAddress endS - 1;
c.numByte = endS;
chunkPot.chunks.push(c);
}
}
} else {
var chunk = {
startByte: 0,
endByte: fileSize - 1,
numByte: fileSize,
};
chunkPot.chunks.push(chunk);
}
return chunkPot;
}
</script>
</body>
</html>
- При запуске вышеупомянутого модифицированного сценария загруженный файл создается в определенную папку и
webContentLink
отображается как результат.
Ссылки:
Комментарии:
1. Это именно то, что я хотел! Я протестировал, и после некоторых ошибок с разрешениями все работает правильно! Большое вам спасибо!
2. @gweintraub Спасибо за ответ. Я рад, что ваша проблема была решена. И вам спасибо.