Управление местоположением загрузки файлов на Google Диске (сценарий приложения, а не форма)

#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:

Я считаю, что ваша цель и ваша текущая ситуация заключаются в следующем.

Точки модификации:

  • В этом случае требуется проверить возобновляемую загрузку и метод «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 Спасибо за ответ. Я рад, что ваша проблема была решена. И вам спасибо.