google.script.run
ist eine asynchrone clientseitige JavaScript API, mit der HTML-Dienstseiten serverseitige Apps Script-Funktionen aufrufen können. Das folgende Beispiel zeigt die grundlegendste Funktion von google.script.run
– eine Funktion auf dem Server aufrufen über clientseitiges 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 Web-App bereitstellen und die URL aufrufen, sehen Sie nichts. Wenn Sie sich jedoch die Logs ansehen, sehen Sie, dass die Serverfunktion doSomething()
aufgerufen wurde.
Clientseitige Aufrufe von serverseitigen Funktionen sind asynchron: Nachdem der Browser angefordert hat, dass der Server die Funktion doSomething()
ausführt, fährt der Browser sofort mit der nächsten Codezeile fort, ohne auf eine Antwort zu warten. Das bedeutet, dass Serverfunktionsaufrufe möglicherweise nicht in der von Ihnen erwarteten Reihenfolge ausgeführt werden. Wenn Sie zwei Funktionsaufrufe gleichzeitig ausführen, ist nicht vorhersehbar, welche Funktion zuerst ausgeführt wird. Das Ergebnis kann sich bei jedem Laden der Seite unterscheiden. In diesem Fall können Sie mit Erfolgs- und Fehler-Handlern den Ablauf Ihres Codes steuern.
Die google.script.run
API ermöglicht 10 gleichzeitige Aufrufe von Serverfunktionen. Wenn Sie einen elften Aufruf starten, während noch zehn ausgeführt werden, wird die Serverfunktion verzögert, bis einer der zehn Plätze frei wird. In der Praxis sollten Sie sich nur selten mit dieser Einschränkung befassen müssen, da die meisten Browser die Anzahl der gleichzeitigen Anfragen an denselben Server bereits auf eine Zahl unter 10 begrenzen.
In Firefox liegt das Limit beispielsweise bei 6. Die meisten Browser verzögern überschüssige Serveranfragen auf ähnliche Weise, bis eine der vorhandenen Anfragen abgeschlossen ist.
Parameter und Rückgabewerte
Sie können eine Serverfunktion mit Parametern vom Client aus aufrufen. Ebenso kann eine Serverfunktion einen Wert an den Client zurückgeben, indem sie ihn als Parameter an einen Erfolgs-Handler übergibt.
Gültige Parameter und Rückgabewerte sind einfache JavaScript-Werte wie Number
, Boolean
, String
oder null
sowie JavaScript-Objekte und ‑Arrays, die aus einfachen Werten, Objekten und Arrays bestehen. Ein form
-Element auf der Seite ist auch als Parameter zulässig, muss aber der einzige Parameter der Funktion sein und ist nicht als Rückgabewert zulässig. Anfragen schlagen fehl, wenn Sie versuchen, ein Date
, Function
, ein DOM-Element außer einem form
oder einen anderen unzulässigen Typ zu übergeben, einschließlich unzulässiger Typen in Objekten oder Arrays. Objekte, die zirkuläre Verweise erstellen, schlagen ebenfalls fehl. Nicht definierte Felder in Arrays werden zu null
.
Ein an den Server übergebenes Objekt ist eine Kopie des Originals. Wenn eine Serverfunktion ein Objekt empfängt und dessen Eigenschaften ändert, sind die Eigenschaften auf dem Client nicht betroffen.
Erfolgs-Handler
Da der clientseitige Code mit der nächsten Zeile fortfährt, ohne auf den Abschluss eines Serveraufrufs zu warten, können Sie mit withSuccessHandler(function)
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 als Parameter an die neue Funktion.
Im folgenden Beispiel wird eine Browserbenachrichtigung angezeigt, wenn der Server antwortet. Für dieses Codebeispiel ist eine Autorisierung erforderlich, da die serverseitige Funktion auf Ihr Gmail-Konto zugreift. Am einfachsten autorisieren Sie das Skript, indem Sie die Funktion getUnreadEmails()
einmal manuell über den Skripteditor ausführen, bevor Sie die Seite laden. Alternativ können Sie beim Bereitstellen der Webanwendung festlegen, dass sie als „Nutzer, der auf die Webanwendung zugreift“ ausgeführt wird. 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 ausgibt, können Sie mit withFailureHandler(function)
anstelle eines Erfolgs-Handlers einen Fehler-Handler angeben. Das Error
-Objekt (falls vorhanden) wird als Argument übergeben.
Wenn Sie keinen Fehler-Handler angeben, werden Fehler standardmäßig in der JavaScript-Konsole protokolliert. Wenn Sie dies überschreiben möchten, rufen Sie withFailureHandler(null)
auf oder geben Sie einen Fehler-Handler an, der nichts tut.
Die Syntax für Fehler-Handler ist fast identisch mit der für Erfolgs-Handler, wie dieses Beispiel zeigt.
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 des Servers wiederverwenden, indem Sie withUserObject(object)
aufrufen, um ein Objekt anzugeben, das als zweiter Parameter an den Handler übergeben wird.
Mit diesem „Nutzerobjekt“ – nicht zu verwechseln mit der Klasse User
– können Sie auf den Kontext reagieren, 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 keine Objekte sein, die mit dem Operator new
erstellt wurden.
In diesem Beispiel wird durch Klicken auf eine der beiden Schaltflächen die jeweilige Schaltfläche mit einem Wert vom Server aktualisiert, während die andere Schaltfläche unverändert bleibt, obwohl beide einen gemeinsamen Success-Handler haben. Im onclick
-Handler bezieht sich das Keyword this
auf 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 aus dem Formular ein einzelnes Objekt mit Feldnamen als Schlüsseln und Feldwerten als Werten. Alle Werte werden in Strings konvertiert, mit Ausnahme des Inhalts von file-input-Feldern, die zu Blob
-Objekten werden.
In diesem Beispiel wird ein Formular mit einem Dateieingabefeld verarbeitet, ohne die Seite neu zu laden. Die Datei wird in Google Drive hochgeladen und die URL für die Datei wird auf der Clientseite ausgegeben. Im onsubmit
-Handler bezieht sich das Keyword this
auf das Formular selbst. Beachten Sie, dass beim Laden aller Formulare auf der Seite die Standard-Sendeaktion durch preventFormSubmit
deaktiviert wird. So wird verhindert, dass die Seite im Falle einer Ausnahme zu einer falschen URL weitergeleitet wird.
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>
Skriptausführer
google.script.run
kann als Builder für einen „Script Runner“ betrachtet werden. Wenn Sie einem Script Runner einen Success-Handler, einen Failure-Handler oder ein Nutzerobjekt hinzufügen, ändern Sie den vorhandenen Runner nicht. Stattdessen erhalten Sie einen neuen Script Runner mit neuem Verhalten.
Sie können eine beliebige Kombination und Reihenfolge von withSuccessHandler()
, withFailureHandler()
und withUserObject()
verwenden. Sie können auch eine der Änderungsfunktionen für einen Script Runner aufrufen, für den bereits ein Wert festgelegt ist. Der neue Wert überschreibt einfach den vorherigen Wert.
In diesem Beispiel wird ein gemeinsamer Fehler-Handler für alle drei Serveraufrufe, 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 keine Funktionen in Bibliotheken und Funktionen sehen, die nicht auf der obersten Ebene des Scripts deklariert sind.
In diesem Beispiel ist die Funktion getBankBalance()
im Clientcode verfügbar. Ein Nutzer, der Ihren Quellcode untersucht, kann den Namen der Funktion ermitteln, auch wenn Sie sie nicht aufrufen. Die Funktionen deepSecret_()
und obj.objectMethod()
sind für den Client jedoch vollständig 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 Apps anpassen
Benutzerdefinierte Dialogfelder in Google Docs, Google Sheets oder Google Formulare können durch Aufrufen der Methoden google.script.host
setWidth(width)
oder setHeight(height)
im clientseitigen Code in der Größe angepasst werden. (Verwenden Sie die HtmlOutput
-Methoden setWidth(width)
und setHeight(height)
, um die ursprüngliche Größe eines Dialogfelds festzulegen.) Dialogfelder werden beim Ändern der Größe nicht im übergeordneten Fenster zentriert. Außerdem ist es nicht möglich, die Größe von Seitenleisten zu ändern.
Dialogfelder und Seitenleisten in Google Workspaceschließen
Wenn Sie den HTML-Dienst verwenden, um ein Dialogfeld oder eine Seitenleiste in Google Docs, Sheets oder Formulare anzuzeigen, können Sie die Benutzeroberflä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 als Google Workspace -Benutzeroberfläche bereitstellen.
Browserfokus in Google Workspaceverschieben
Wenn Sie den Fokus im Browser des Nutzers von einem Dialogfeld oder einer Seitenleiste zurück zum Editor von Google Docs, Google Sheets oder Google Formulare verschieben möchten, rufen Sie einfach die Methode google.script.host.editor.focus()
auf.
Diese Methode ist besonders nützlich in Kombination mit den Document Service-Methoden Document.setCursor(position)
und Document.setSelection(range)
.