首頁  >  問答  >  主體

使用 Google Apps 腳本直接將文件上傳到我的 Google 雲端硬碟(不使用 Google 表單)

所以基本上任務非常簡單,但我沒有找到任何可行的解決方案來解決我的問題。我的網站上有一個巨大的上傳腳本(目前是本地主機),但讓我們將所有複雜性減少到唯一必要的程度。

所以我只想使用 Google App Script 將單一檔案上傳到 Google 雲端硬碟,並接收它的 URL 以將其保存在 var 中,以便稍後在我的函數中使用該資訊。

現在的問題是我的網站上已經有該表單,我不希望script.google .com 內的表單作為額外的html,我想將我的用戶輸入傳輸到Google App Script,然後將其上傳到google 驅動器並將url 返回到我的網站,我可以將其儲存到var 中。

我現在的問題是,我無法將所有的東西放在一起。

這是我網站上的表格(簡化):

#
<form name="myForm" method="post">
            <!-- <form name="first-form"> -->

  <input type="text" placeholder="Name" id="myName">
  <input type="file" name="myFile" id="myFile">
  <button onclick="UploadFile()" type="submit">submit</button>

</form>

那麼我要如何在 Google Drive 中上傳我的資訊並取得結果呢?如何在不使用 iFrame 或其他任何東西的情況下推送 Google App 腳本中的資料?

謝謝!

**** 如果 html 位於 script.google .com 中,則工作範例 ****

GS

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('forms.html').setTitle("Google File Upload by CTRLQ.org");
}


function uploadFileToGoogleDrive(data, file, name, email) {
  
  try {
    
    var dropbox = "Received Files";
    var folder, folders = DriveApp.getFoldersByName(dropbox);
    
    if (folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = DriveApp.createFolder(dropbox);
    }
    
    /* Credit: www.labnol.org/awesome */
    
    var contentType = data.substring(5,data.indexOf(';')),
        bytes = Utilities.base64Decode(data.substr(data.indexOf('base64,')+7)),
        blob = Utilities.newBlob(bytes, contentType, file),
        file = folder.createFolder([name, email].join(" ")).createFile(blob);
    
    return "OK";
    
  } catch (f) {
    return f.toString();
  }
  
}

apps.googlescript 中的 html

<!DOCTYPE html>
<html>
  <head>
    <base target="_blank">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Google File Upload by CTRLQ.org</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css">
    <style>
      .disclaimer{width: 480px; color:#646464;margin:20px auto;padding:0 16px;text-align:center;font:400 12px Roboto,Helvetica,Arial,sans-serif}.disclaimer a{color:#009688}#credit{display:none}
    </style>
  </head>
  <body>

    <!-- Written by Amit Agarwal amit@labnol.org --> 

    <form class="main" id="form" novalidate="novalidate" style="max-width: 480px;margin: 40px auto;">
      <div id="forminner">
        <div class="row">
          <div class="col s12">
            <h5 class="center-align teal-text">Upload Files to my Google Drive</h5>
            <p class="disclaimer">This <a href="http://www.labnol.org/internet/file-upload-google-forms/29170/">File Upload Form</a> (<a href="https://youtu.be/C_YBBupebvE">tutorial</a>) is powered by <a href="https://ctrlq.org/code/19747-google-forms-upload-files" target="_blank">Google Scripts</a></p>
          </div>
        </div>
        <div class="row">
          <div class="input-field col s12">
            <input id="name" type="text" name="Name" class="validate" required="" aria-required="true">
            <label for="name">Name</label>
          </div>
        </div>
        <div class="row">
          <div class="input-field col s12">
            <input id="email" type="email" name="Email" class="validate" required="" aria-required="true">
            <label for="email">Email Address</label>
          </div>
        </div>

        <div class="row">
          <div class="file-field input-field col s12">
            <div class="btn">
              <span>File</span>
              <input id="files" type="file">
            </div>
            <div class="file-path-wrapper">
              <input class="file-path validate" type="text" placeholder="Select a file on your computer">
            </div>
          </div>
        </div>

        <div class="row">
          <div class="input-field col s6">
            <button class="waves-effect waves-light btn submit-btn" type="submit" onclick="submitForm(); return false;">Submit</button>
          </div>   
        </div>
        <div class="row">
          <div class="input-field col s12" id = "progress">
          </div>
        </div>
      </div>
      <div id="success" style="display:none">
        <h5 class="left-align teal-text">File Uploaded</h5>
        <p>Your file has been successfully uploaded.</p>
        <p>The <a href="http://www.labnol.org/internet/file-upload-google-forms/29170/">pro version</a> (see <a href="">demo form</a>) includes a visual drag-n-drop form builder, CAPTCHAs, the form responses are saved in a Google Spreadsheet and respondents can upload multiple files of any size.</p>    
        <p class="center-align"><a  class="btn btn-large" href="https://gum.co/GA14?wanted=true" target="_blank">Upgrade to Pro</a></p>
      </div>
    </form>

    <div class="fixed-action-btn horizontal" style="bottom: 45px; right: 24px;">
      <a class="btn-floating btn-large red">
        <i class="large material-icons">menu</i>
      </a>
      <ul>
        <li><a class="btn-floating red"  href="https://gum.co/GA14" target="_blank" title="Buy License - File Upload Form"><i class="material-icons">monetization_on</i></a></li>
        <li><a class="btn-floating blue"  href="https://youtu.be/C_YBBupebvE" target="_blank" title="Video Tutorial"><i class="material-icons">video_library</i></a></li>
        <li><a class="btn-floating green" href="http://www.labnol.org/internet/file-upload-google-forms/29170/" target="_blank" title="How to Create File Upload Forms"><i class="material-icons">help</i></a></li>
      </ul>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js"></script>
    <script src="https://gumroad.com/js/gumroad.js"></script>

    <script>

      var file, 
          reader = new FileReader();

      reader.onloadend = function(e) {
        if (e.target.error != null) {
          showError("File " + file.name + " could not be read.");
          return;
        } else {
          google.script.run
            .withSuccessHandler(showSuccess)
            .uploadFileToGoogleDrive(e.target.result, file.name, $('input#name').val(), $('input#email').val());
        }
      };

      function showSuccess(e) {
        if (e === "OK") { 
          $('#forminner').hide();
          $('#success').show();
        } else {
          showError(e);
        }
      }

      function submitForm() {

        var files = $('#files')[0].files;

        if (files.length === 0) {
          showError("Please select a file to upload");
          return;
        }

        file = files[0];

        if (file.size > 1024 * 1024 * 5) {
          showError("The file size should be < 5 MB. Please <a href='http://www.labnol.org/internet/file-upload-google-forms/29170/' target='_blank'>upgrade to premium</a> for receiving larger files in Google Drive");
          return;
        }

        showMessage("Uploading file..");

        reader.readAsDataURL(file);

      }

      function showError(e) {
        $('#progress').addClass('red-text').html(e);
      }

      function showMessage(e) {
        $('#progress').removeClass('red-text').html(e);
      }


    </script>

  </body>

</html>

按照建議,我將在這裡描述該過程。

所以我們在網站上:www.example.com,有一個帶有文字輸入欄位和檔案欄位的表單。假設我們放入一張圖像並將其稱為範例。現在,如果我們按提交,我想將圖像上傳到谷歌驅動器,而不需要任何oAuth(這就是為什麼我們需要在此處使用谷歌應用程式腳本)並將其命名為我們在文字欄位中鍵入的內容。上傳完成後,我希望將 google Drive 圖像的 url 返回網站,以便表單可以繼續使用該資訊。我想將返回的 url 保存在 var 中,稍後將其保存在資料庫中。這就是為什麼我需要將結果返回到我的網站。

因此方案如下所示:

在網站上輸入資訊到表單-> 重定向到google 應用程式腳本:獲取網站表單欄位的資訊並將文件上傳到google 驅動器,並將其命名為文字輸入條目-> 將google 驅動器的url 作為最終結果-> 重定向最終url 結果返回網站-> 將url 結果保存在var 中並繼續從網站-> 上的函數執行操作,最後將var 中的信息保存到數據庫-> finish

----------------------------------------------- ------------- - 編輯: ------------------

感謝@Tanaike,我離我的挑戰目標更近了,所以為了看看我陷入了困境,我現在正在複製我的問題:

我使用您範例中的腳本取得了表單:

<form id="form">
  <input name="file" id="uploadfile" type="file">
  <input name="filename" id="filename" type="text">
  <input id="submit" type="submit">
</form>
<script>
const form = document.getElementById('form');
form.addEventLis tener('submit', e => {
  e.preventDefault();
  const file = form.file.files[0];
  const fr = new FileReader();
  fr.readAsArrayBuffer(file);
  fr.onload = f => {
    
    const url = "https://script.google .com/macros/s/###/exec";  // <--- Please set the URL of Web Apps.
    
    const qs = new URLSearchParams({filename: form.filename.value || file.name, mimeType: file.type});
    fetch(`${url}?${qs}`, {method: "POST", body: JSON.stringify([...new Int8Array(f.target.result)])})
    .then(res => res.json())
    .then(e => console.log(e))  // <--- You can retrieve the returned value here.
    .catch(err => console.log(err));
  }
});
</script>

對於Google腳本:

function doPost(e) {
  // const folderId = "###";  // Folder ID which is used for putting the file, if you need.

  const blob = Utilities.newBlob(JSON.parse(e.postData.contents), e.parameter.mimeType, e.parameter.filename);
  const file = DriveApp.getFolderById(folderId || "root").createFile(blob);
  const responseObj = {filename: file.getName(), fileId: file.getId(), fileUrl: file.getUrl()};
  return ContentService.createTextOutput(JSON.stringify(responseObj)).setMimeType(ContentService.MimeType.JSON);
}

現在,當我嘗試上傳某些內容時,出現以下錯誤:CORS 策略無法取得。所以我將這部分更改為以下內容並添加了 no cors 模式:

const qs = new URLSearchParams({filename: form.filename.value || file.name, mimeType: file.type});
        fetch(`${url}?${qs}`, {method: "POST", mode: "no-cors", body: JSON.stringify([...new Int8Array(f.target.result)])})

這有效。第二次嘗試上傳檔案導致以下錯誤: 它說:syntax錯誤:輸入意外結束

所以我更改了這一行並從 res.json 中刪除了括號

JSON.stringify([...new Int8Array(f.target.result)])})
        .then(res => res.json)

第三次嘗試上傳實際有效的文件,控制台結果如下:

ƒ json() { [native code] }

但是 Google 雲端硬碟中沒有上傳檔案。我在某個地方缺少一些東西。也許我們應該創建一個資料夾並將文件放入其中。

哦,還有另一個訊息:當我在 google app sript 中執行 doPost 函數時,它說:

TypeError: Cannot read property 'postData' of undefined (line 13

編輯2 --------------------------------------------- --------

我將 https://drive.google .com/uc?export=download&id=

fileId

加入到您的程式碼中,一切正常。文件正在上傳。

假設我們上傳檔案 test.mp3,並將其命名為 testdata。 這是我們收到的:

{
  "filename": "testdata",
  "fileId": "###some id##",
  "fileUrl": "https://drive.google .com/uc?export=download&id=###fileId###"
}

現在,當我開啟文件 url 時,瀏覽器會下載文件,但其名稱為:testdata,而不是 testdata.mp3。文件類型結尾遺失。

第二個任務:如果您單擊鏈接,我想在瀏覽器中打開該文件,例如,當它是mp3 文件時,我希望您可以在webview 中播放聲音,就像這裡一樣:https: //files.freemusicarchive .org/storage-freemusicarchive-org/music/Creative_Commons/Dead_Combo/CC_Affiliates_Mixtape_1/Dead_Combo_-_01_-_Povo_Que_Cas_Decalo.mp3

######################### ###希望您能指導我! ######
P粉785905797P粉785905797272 天前506

全部回覆(2)我來回復

  • P粉512729862

    P粉5127298622024-01-22 14:32:10

    https://stackoverflow.com/a/63391363/1585523 答案中有很多有用的提示!感謝你的分享。除了 POST 檔案之外,我們還可以使用

    在客戶端:index.html

    google.script.run.withSuccessHandler(fileName => {}).withFailureHandler(error => {}).saveInDrive(fileAsByteArray);
    

    在伺服器上:Code.gs

    function saveInDrive(f) {
      const blob = Utilities.newBlob(f, "image/jpeg", "some-name");
      const file = DriveApp.getFolderById("root").createFile(blob);
      return file.getName()
    }
    

    您甚至可以用這種方法交換複雜類型,例如 JS 物件與二進位資訊作為值。

    回覆
    0
  • P粉298305266

    P粉2983052662024-01-22 13:48:47

    我相信您的目標如下。

    • 您的網站與 Google 帳戶無關。它是獨立的。
    • 您的網站有一個用於上傳文件的表單。
    • 當使用者提交表單時,您希望在未經授權的情況下將文件上傳到您的 Google 雲端硬碟,並希望返回已上傳文件在 Google 雲端硬碟上的網址。
    • 關於“資料庫”,這是您的資料庫。您將檢索到的文件 URL 放入客戶端的「資料庫」中。

    在這種情況下,我認為使用 Google Apps 腳本建立的網路應用程式可以實現您的目標。

    用法:

    請執行以下流程。

    1。建立 Google Apps 腳本的新專案。

    Web Apps 的範例腳本是 Google Apps 腳本。因此,請建立一個 Google Apps 腳本專案。

    如果您想直接創建,請造訪https://script.new/。在這種情況下,如果您尚未登入 Google,則會開啟登入畫面。所以請登入谷歌。這樣,Google Apps 腳本的腳本編輯器就會開啟。

    2。準備腳本。

    請將以下腳本(Google Apps 腳本)複製並貼上到腳本編輯器中。該腳本適用於網頁應用程式。

    伺服器端:Google Apps 腳本

    請設定要放置檔案的資料夾ID。

    function doPost(e) {
      const folderId = "root";  // Or Folder ID which is used for putting the file instead of "root", if you need.
    
      const blob = Utilities.newBlob(JSON.parse(e.postData.contents), e.parameter.mimeType, e.parameter.filename);
      const file = DriveApp.getFolderById(folderId).createFile(blob);
      const responseObj = {filename: file.getName(), fileId: file.getId(), fileUrl: file.getUrl()};
      return ContentService.createTextOutput(JSON.stringify(responseObj)).setMimeType(ContentService.MimeType.JSON);
    }

    3。部署網路應用程式。

    1. 在腳本編輯器中,透過「發布」->「部署為網路應用程式」開啟一個對話框。
    2. 「執行應用程式:」選擇「我」
      • 這樣,腳本就會以擁有者的身分執行。
    3. 「誰有權存取該應用程式:」選擇「任何人,甚至匿名」
    4. 點擊「部署」按鈕作為新的「專案版本」。
    5. 自動開啟「需要授權」對話方塊。
      1. 點選「檢視權限」。
      2. 選擇自己的帳戶。
      3. 點選「此應用程式未經驗證」處的「進階」。
      4. 點選「前往
      5. 項目名稱
      6. (不安全)」
      點擊「允許」按鈕。
    6. 點選「確定」。 複製網頁應用程式的 URL。就像
        https://script.google.com/macros/s/
      • /exec
      修改 Google Apps 腳本後,請重新部署為新版本。這樣,修改後的腳本就會反映在Web Apps中。請小心這一點。

    4。從客戶端上傳文件到伺服器端。

    客戶端:HTML 與 Javascript
    • 請將您的 Web 應用程式的 URL 設定為以下腳本。
    • sssccc

    在用戶端,當您從本機 PC 選擇檔案並按下按鈕時,系統會透過在網路應用程式(伺服器端)檢索資料來將該檔案上傳到您的 Google 雲端硬碟。

    結果:### ###執行上述腳本時,將傳回以下值。由此,您可以檢索文件的 URL。 ###
    {
      "filename": "### inputted filename ###",
      "fileId": "###",
      "fileUrl": "https://drive.google.com/file/d/###/view?usp=drivesdk"
    }

    注意:

    • 當您修改Web Apps的腳本時,請將Web Apps重新部署為新版本。這樣,最新的腳本就會反映在Web Apps中。請小心這一點。
    • 在上面的腳本中,最大檔案大小為 50 MB。因為在目前階段,Google Apps 腳本的最大 blob 大小為 50 MB。

    參考文獻:

    #

    回覆
    0
  • 取消回覆