HTML-Dienst: Mit Serverfunktionen kommunizieren

google.script.run ist ein asynchroner clientseitige JavaScript API, die es HTML-Dienstseiten ermöglicht, serverseitige Apps Script-Funktionen Das folgende Beispiel zeigt die grundlegendsten Funktionen von google.script.runFunktion auf dem Server aufrufen aus clientseitigem JavaScript.

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>

Wenn Sie dieses Skript als Webanwendung bereitstellen und dessen URL aufrufen, etwas anderes, aber in den Protokollen sehen Sie, dass die Serverfunktion doSomething() wurde angerufen.

Clientseitige Aufrufe serverseitiger Funktionen erfolgen asynchron: nach dem Browser anfordert, dass der Server die Funktion doSomething() ausführt, fährt der Browser fort, direkt in die nächste Codezeile, ohne auf eine Antwort warten zu müssen. Das bedeutet, dass Serverfunktionsaufrufe möglicherweise nicht in der erwarteten Reihenfolge ausgeführt werden. Wenn Sie zwei Funktionsaufrufe gleichzeitig ausführen, lässt sich nicht vorhersagen, welche Funktion zuerst ausgeführt wird. Das Ergebnis kann sich jedes Mal unterscheiden, wenn Sie die Seite laden. In dieser Situation Erfolgs-Handler und Fehler-Handler Ihren Code zu steuern.

Die google.script.run API ermöglicht zehn gleichzeitige Aufrufe von Serverfunktionen. Wenn und einen elften Aufruf ausführen, während 10 noch ausgeführt werden, wird die Serverfunktion bis einer der zehn Plätze frei ist. In der Praxis sollten Sie über diese Einschränkung nachdenken, zumal die meisten Browser bereits die Anzahl gleichzeitiger Anfragen an denselben Server unter 10 In Firefox zum Beispiel beträgt die Beschränkung 6. Die meisten Browser verzögern ähnliche Serveranfragen, bis eine der bestehenden Anfragen abgeschlossen ist.

Parameter und Rückgabewerte

Sie können eine Serverfunktion mit Parametern aus dem Client aufrufen. Ähnlich verhält es sich bei einem Server-Funktion kann einen Wert an den Client als Parameter zurückgeben, der an einen Erfolgs-Handler.

Zulässige Parameter und Rückgabewerte sind JavaScript-Primitive wie Number, Boolean, String oder null sowie JavaScript-Objekte und -Arrays, die aus Primitiven, Objekten und Arrays. Ein form-Element auf der Seite ist auch als Parameter zulässig, muss aber der einzige Parameter der Funktion sein. ist kein Rückgabewert zulässig. Anfragen schlagen fehl, wenn Sie versuchen, ein Date-, Function- oder DOM-Element außer einem form oder einen anderen nicht zulässigen Typ zu übergeben, einschließlich nicht zulässiger Typen in Objekten oder Arrays. Objekte, durch die Zirkelbezüge schlagen ebenfalls fehl und undefinierte Felder innerhalb von Arrays werden zu null

Beachten Sie, dass ein an den Server übergebenes Objekt zu einer Kopie des Originals wird. Wenn ein Serverfunktion ein Objekt empfängt und seine Eigenschaften ändert, die Eigenschaften von nicht betroffen sind.

Erfolgs-Handler

Weil clientseitiger Code in der nächsten Zeile fortgesetzt wird, ohne auf einen Server zu warten um einen entsprechenden Anruf zu tätigen, withSuccessHandler(function) können Sie eine clientseitige Callback-Funktion angeben, die ausgeführt wird, wenn der Server antwortet. Wenn die Serverfunktion einen Wert zurückgibt, übergibt die API den Wert an die neue Funktion als Parameter.

Im folgenden Beispiel wird eine Browserwarnung angezeigt, wenn der Server antwortet. Hinweis dass dieses Codebeispiel eine Autorisierung erfordert, da die serverseitige Funktion auf Ihr Gmail-Konto zugreifen. Die einfachste Möglichkeit, das Skript zu autorisieren, ist die Ausführung die getUnreadEmails()-Funktion einmal manuell über den Skripteditor um die Seite zu laden. Alternativ können Sie beim Bereitstellen der Webanwendung festlegen, dass sie als „Nutzer, der auf die Webanwendung zugreift“ ausgeführt werden soll. In diesem Fall werden Sie beim Laden der App zur Autorisierung aufgefordert.

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>

Fehler-Handler

Falls der Server nicht antwortet oder einen Fehler auslöst, können Sie mit withFailureHandler(function) einen Fehler-Handler anstelle eines Erfolgs-Handlers angeben. Das Error-Objekt (falls vorhanden) wird als Argument übergeben.

Wenn Sie keinen Fehler-Handler angeben, werden Fehler standardmäßig im JavaScript-Konsole. Rufen Sie zum Überschreiben withFailureHandler(null) auf oder geben Sie Fehler-Handler, der nichts tut.

Die Syntax für Fehler-Handler ist fast identisch mit Erfolgs-Handlern, da Beispiel-Shows.

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>

Nutzerobjekte

Sie können denselben Erfolgs- oder Fehler-Handler für mehrere Aufrufe der mit einem Aufruf von withUserObject(object) , um ein Objekt anzugeben, das als zweiter Parameter an den Handler übergeben wird. Dieses „Nutzerobjekt“ ist nicht zu verwechseln mit dem Klasse User: Sie können auf die Kontext, in dem der Client den Server kontaktiert hat. Da Nutzerobjekte nicht an den Server gesendet werden, können sie fast alles sein, einschließlich Funktionen, DOM- Elemente usw. ohne die Einschränkungen für Parameter und Rückgabewerte für Serveraufrufe. Nutzerobjekte können jedoch nicht mit dem Operator new.

In diesem Beispiel wird durch Klicken auf eine der beiden Schaltflächen diese Schaltfläche mit einem Wert vom Server aktualisiert, während die andere Schaltfläche unverändert bleibt, obwohl sie denselben Erfolgs-Handler teilen. Im onclick-Handler bezieht sich das Keyword this auf die button selbst.

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>

Formulare

Wenn Sie eine Serverfunktion mit einem form-Element als Parameter aufrufen, wird das Format wird ein einzelnes Objekt mit Feldnamen als Schlüsseln und Feldwerten als Werte. Die -Werte werden alle in Strings konvertiert, mit Ausnahme des Inhalts von file-input -Feldern, die zu Blob-Objekten werden.

In diesem Beispiel wird ein Formular einschließlich Dateieingabefeld verarbeitet, ohne es neu zu laden. der Seite; wird die Datei in Google Drive hochgeladen und dann die URL für den -Datei auf der clientseitigen Seite. Im onsubmit-Handler wird das Schlüsselwort this bezieht sich auf das Formular selbst. Beim Laden aller Formulare auf der Seite wird die standardmäßige Sendeaktion durch preventFormSubmit deaktiviert. Dadurch wird verhindert, dass im Falle einer Ausnahme die Weiterleitung zu einer fehlerhaften URL deaktiviert.

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>

Script-Runner

Stellen Sie sich google.script.run als Builder für einen Script-Runner vor. Wenn Sie Erfolgs-Handler, Fehler-Handler oder Nutzerobjekt zu einem Skript-Runner hinzufügen, den vorhandenen Läufer nicht ändern; erhalten Sie stattdessen einen neuen Skript-Runner zurück, mit neuen Verhaltensmustern.

Sie können eine beliebige Kombination und Reihenfolge von withSuccessHandler() verwenden, withFailureHandler() und withUserObject(). Sie können auch eine der Funktionen eines Skript-Ausführers ändern, für den bereits ein Wert festgelegt ist. Das neue überschreibt einfach den vorherigen Wert.

In diesem Beispiel wird für alle drei Serveraufrufe ein gemeinsamer Fehler-Handler, aber zwei separate Erfolgs-Handler festgelegt:

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

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

Private Funktionen

Serverfunktionen, deren Namen mit einem Unterstrich enden, gelten als privat. Diese Funktionen können nicht von google.script aufgerufen werden und ihre Namen werden nie an den Client gesendet. Sie können damit Implementierungsdetails ausblenden, die auf dem Server geheim gehalten werden müssen. google.script kann auch nichts sehen Funktionen in Bibliotheken und Funktionen, die nicht das auf oberster Ebene des Skripts festgelegt wurde.

In diesem Beispiel ist die Funktion getBankBalance() im Client verfügbar. Code; kann ein Nutzer, der Ihren Quellcode überprüft, seinen Namen auch dann finden, wenn Sie nennen Sie ihn nicht. Die Funktionen deepSecret_() und obj.objectMethod() sind für den Client jedoch völlig unsichtbar.

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>

Größe von Dialogfeldern in Google Workspace Anwendungen anpassen

Benutzerdefinierte Dialogfelder in Google Docs, Google Tabellen oder Sie können die Größe von Formularen durch Aufrufen der google.script.host-Methoden setWidth(width) oder setHeight(height) in clientseitigen Code. Um die ursprüngliche Größe eines Dialogfelds festzulegen, verwenden Sie die HtmlOutput-Methoden setWidth(width) und setHeight(height). Dialogfelder werden beim Ändern der Größe nicht im übergeordneten Fenster neu zentriert. Seitenleisten können nicht geändert werden.

Dialogfelder und Seitenleisten in Google Workspacewerden geschlossen

Wenn Sie mit dem HTML-Dienst eine Dialogfeld oder Seitenleiste in Google Docs, Google Tabellen oder Formulare können Sie die Oberfläche nicht durch Aufrufen von window.close() schließen. Stattdessen müssen Sie google.script.host.close() aufrufen. Ein Beispiel finden Sie im Abschnitt HTML-Bereitstellung als Google Workspace Benutzeroberfläche.

Fokus des Browsers wird nach Google Workspaceverschoben

Wenn Sie den Fokus im Browser des Nutzers von einem Dialogfeld oder einer Seitenleiste zurück zum Editor von Google Docs, Google Tabellen oder Google Formulare wechseln möchten, rufen Sie einfach die Methode google.script.host.editor.focus() auf. Diese Methode ist besonders nützlich in Kombination mit der Document service-Methoden Document.setCursor(position) und Document.setSelection(range)