HTML 服務:與伺服器函式通訊

google.script.run 是非同步 可讓 HTML 服務頁面呼叫伺服器端的用戶端 JavaScript API Apps Script 函式。以下範例顯示最基本的功能 /google.script.run - 在伺服器上呼叫函式

Code.gs

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function doSomething() {
  Logger.log('I was called!');
}

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      google.script.run.doSomething();
    </script>
  </head>
</html>

如果您是將這個指令碼部署為網頁應用程式,並造訪其網址,就不會 但如果您查看記錄檔,就會發現伺服器函數 已呼叫 doSomething()

用戶端函式的用戶端呼叫是以非同步的方式進行:在瀏覽器之後 要求伺服器執行 doSomething() 函式,瀏覽器繼續進行 不必等待回應。也就是說 伺服器函式呼叫可能無法按您預期的順序執行。如果 同時,有兩個函式呼叫時,無法得知哪個函式會 先執行;每次載入網頁時的結果可能有所不同。在此情況下 成功處理常式失敗處理常式 有助於控製程式碼流程

google.script.run API 允許對伺服器函式並行 10 次呼叫。如果 您在 10 都執行時發出第 11 次呼叫,伺服器函式就會 等到 10 個名額釋出為止。實務上,您應該很少 考量這項限制,特別是因為大部分的瀏覽器都設有限制 對相同伺服器的並行要求數量低於 10。 例如,Firefox 的上限為 6 個。大多數瀏覽器也同樣有延遲時間 伺服器傳送要求,直到現有的其中一個要求完成為止。

參數和傳回值

您可以使用用戶端的參數呼叫伺服器函式。同樣地, 伺服器函數會將值傳回給用戶端,做為傳遞至 成功處理常式

法律參數和傳回值是 JavaScript 基元,例如 NumberBooleanStringnull,以及會用來處理 由基元、物件和陣列組成網頁中的 form 元素 也同樣合法,但必須是函式的唯一參數,且 不合法的回傳值如果您嘗試 DateFunction、DOM 元素以外的 form 或其他禁止類型。 包括物件或陣列中禁止的類型。建立的物件 循環參照也會失敗,而陣列中的未定義欄位會變成 null

請注意,傳遞至伺服器的物件會成為原始項目的副本。如果 伺服器函數接收物件並變更其屬性, 則不受影響。

成功處理常式

因為用戶端程式碼繼續顯示在下一行,無需等待伺服器 呼叫完成 withSuccessHandler(function)敬上 可讓您指定要在伺服器執行時執行的用戶端回呼函式 給予回應。如果伺服器函式傳回值,API 就會將該值傳送至 將新函式做為參數使用

以下範例會在伺服器回應時顯示瀏覽器快訊。注意事項 這個程式碼範例需要授權,因為伺服器端函式 登入您的 Gmail 帳戶。授權指令碼最簡單的方法就是執行 請在指令碼編輯器中手動執行 getUnreadEmails() 函式, 載入網頁。另一個原因是 部署網頁應用程式時,您可以選擇 以「使用者存取網頁應用程式」的方式執行 並在載入應用程式時提示授權。

Code.gs

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getUnreadEmails() {
  return GmailApp.getInboxUnreadCount();
}

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function onSuccess(numUnread) {
        var div = document.getElementById('output');
        div.innerHTML = 'You have ' + numUnread
            + ' unread messages in your Gmail inbox.';
      }

      google.script.run.withSuccessHandler(onSuccess)
          .getUnreadEmails();
    </script>
  </head>
  <body>
    <div id="output"></div>
  </body>
</html>

失敗處理常式

如果伺服器無法回應或擲回錯誤, withFailureHandler(function)敬上 可讓您指定失敗處理常式 (而不是成功處理常式),使用 Error 物件 (如果有的話) 做為引數。

根據預設,如果您沒有指定失敗處理常式,系統會將失敗記錄在 。如要覆寫這項設定,請呼叫 withFailureHandler(null) 或供應器 不執行任何作業的失敗處理常式

失敗處理常式的語法與成功處理常式幾乎相同, 範例所示

Code.gs

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getUnreadEmails() {
  // 'got' instead of 'get' will throw an error.
  return GmailApp.gotInboxUnreadCount();
}

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function onFailure(error) {
        var div = document.getElementById('output');
        div.innerHTML = "ERROR: " + error.message;
      }

      google.script.run.withFailureHandler(onFailure)
          .getUnreadEmails();
    </script>
  </head>
  <body>
    <div id="output"></div>
  </body>
</html>

User 物件

您可以在多次呼叫 透過 withUserObject(object)敬上 指定要傳遞至處理常式的物件,做為第二個參數。 這個「使用者物件」與 User 類別:供您回覆 用戶端與伺服器連線時的內容。由於使用者物件 可以是幾乎任何項目,包括函式、DOM 等 元素等等,則不受參數和傳回值的限制 。不過,User 物件不能是以 new 運算子。

在此範例中,按一下兩個按鈕之一 值,而另一個按鈕則保持不變 共用一個成功處理常式在 onclick 處理常式中,關鍵字 this 參照 button 本身。

Code.gs

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getEmail() {
  return Session.getActiveUser().getEmail();
}

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function updateButton(email, button) {
        button.value = 'Clicked by ' + email;
      }
    </script>
  </head>
  <body>
    <input type="button" value="Not Clicked"
      onclick="google.script.run
          .withSuccessHandler(updateButton)
          .withUserObject(this)
          .getEmail()" />
    <input type="button" value="Not Clicked"
      onclick="google.script.run
          .withSuccessHandler(updateButton)
          .withUserObject(this)
          .getEmail()" />
  </body>
</html>

表單

如果您使用 form 元素做為參數來呼叫伺服器函式,則表單形式為 會成為單一物件,並以欄位名稱做為鍵和欄位值。 除了檔案輸入的內容之外,所有的值都會轉換為字串 這些欄位會成為 Blob 物件。

這個範例會處理表單,包括檔案輸入欄位,並未重新載入 。將檔案上傳至 Google 雲端硬碟,然後輸出 該檔案位於用戶端網頁中在 onsubmit 處理常式中,關鍵字 this 表單本身。請注意,載入網頁中的所有表單時 預設的提交動作被 preventFormSubmit 停用。這樣一來, 網頁重新導向不正確的網址,

Code.gs

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function processForm(formObject) {
  var formBlob = formObject.myFile;
  var driveFile = DriveApp.createFile(formBlob);
  return driveFile.getUrl();
}

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      // Prevent forms from submitting.
      function preventFormSubmit() {
        var forms = document.querySelectorAll('form');
        for (var i = 0; i < forms.length; i++) {
          forms[i].addEventListener('submit', function(event) {
            event.preventDefault();
          });
        }
      }
      window.addEventListener('load', preventFormSubmit);

      function handleFormSubmit(formObject) {
        google.script.run.withSuccessHandler(updateUrl).processForm(formObject);
      }
      function updateUrl(url) {
        var div = document.getElementById('output');
        div.innerHTML = '<a href="' + url + '">Got it!</a>';
      }
    </script>
  </head>
  <body>
    <form id="myForm" onsubmit="handleFormSubmit(this)">
      <input name="myFile" type="file" />
      <input type="submit" value="Submit" />
    </form>
    <div id="output"></div>
 </body>
</html>

指令碼執行器

您可以將 google.script.run 視為「指令碼執行器」的建構工具。如果發生以下情況: 您可以將成功處理常式、失敗處理常式或使用者物件新增至指令碼執行器,那麼 這不會變更現有的執行器您只需要取得新的指令碼執行器 新的行為

您可以使用 withSuccessHandler()withFailureHandler()withUserObject()。您也可以呼叫 在已設定值的指令碼執行器上修改函式。而 值就會覆寫先前的值。

此範例會為所有三個伺服器呼叫設定一個常見的失敗處理常式,但 不同的成功處理常式:

var myRunner = google.script.run.withFailureHandler(onFailure);
var myRunner1 = myRunner.withSuccessHandler(onSuccess);
var myRunner2 = myRunner.withSuccessHandler(onDifferentSuccess);

myRunner1.doSomething();
myRunner1.doSomethingElse();
myRunner2.doSomething();

Private 函式

名稱結尾為底線的伺服器函式會視為不公開。 google.script 無法呼叫這些函式,其名稱一律不會 資料。因此,您可以利用這些函式,隱藏會隱藏的實作詳細資料 不必在伺服器上加以保密google.script也看不到 函式與非函式中使用的函式 宣告內容

在這個範例中,getBankBalance() 函式可用於用戶端 程式碼;檢查原始碼的使用者可以在您發現原始碼時 不要叫它。但 deepSecret_()obj.objectMethod() 函式完全看不見 用戶端。

Code.gs

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getBankBalance() {
  var email = Session.getActiveUser().getEmail()
  return deepSecret_(email);
}

function deepSecret_(email) {
 // Do some secret calculations
 return email + ' has $1,000,000 in the bank.';
}

var obj = {
  objectMethod: function() {
    // More secret calculations
  }
};

Index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function onSuccess(balance) {
        var div = document.getElementById('output');
        div.innerHTML = balance;
      }

      google.script.run.withSuccessHandler(onSuccess)
          .getBankBalance();
    </script>
  </head>
  <body>
    <div id="output">No result yet...</div>
  </body>
</html>

調整 Google Workspace 應用程式中的對話方塊大小

Google 文件、試算表或 Google 文件中的自訂對話方塊 如要調整表單大小,請呼叫 google.script.host 種方式 setWidth(width)setHeight(height) 英吋 用戶端程式碼(如要設定對話方塊的初始大小,請使用 HtmlOutput 方法 setWidth(width)setHeight(height)。 請注意,調整大小後,對話方塊不會重新置中。 無法調整側欄大小。

正在關閉「 Google Workspace」中的對話方塊和側欄

如果您使用 HTML 服務來顯示 Google 文件、試算表或試算表的對話方塊或側欄 Google 表單無法藉由呼叫 window.close() 關閉介面。而是 必須呼叫。 google.script.host.close()。 如需範例,請參閱 以 Google Workspace 使用者介面提供 HTML。

正在將瀏覽器焦點移至「 Google Workspace」

如何將使用者瀏覽器的焦點從對話方塊或側欄切換回 Google 文件、試算表或表單編輯器,只要在 google.script.host.editor.focus()。 如果同時使用 文件服務方法 Document.setCursor(position)敬上 和 Document.setSelection(range)