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 — den Aufruf einer Funktion auf dem
Server ü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 Webanwendung 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 serverseitige Funktionsaufrufe möglicherweise nicht in der von Ihnen erwarteten Reihenfolge ausgeführt werden. Wenn Sie zwei Funktionsaufrufe gleichzeitig ausführen, lässt sich nicht feststellen, welche Funktion zuerst ausgeführt wird. Das Ergebnis kann sich bei jedem Laden der Seite unterscheiden. In dieser Situation helfen
Erfolgs-Handler und Fehler-Handler
, den Ablauf Ihres Codes zu steuern.
Die google.script.run API ermöglicht 10 gleichzeitige Aufrufe von Serverfunktionen. Wenn Sie einen elften Aufruf ausführen, während noch 10 ausgeführt werden, wird die Serverfunktion verzögert, bis einer der 10 Plätze frei wird. In der Praxis sollten Sie sich selten Gedanken über diese Einschränkung machen müssen, da die meisten Browser die Anzahl gleichzeitiger Anfragen an denselben Server bereits auf einen Wert unter 10 beschränken.
In Firefox liegt das Limit beispielsweise bei 6. Die meisten Browser verzögern überschüssige Serveranfragen ebenfalls, bis eine der vorhandenen Anfragen abgeschlossen ist.
Parameter und Rückgabewerte
Rufen Sie eine Serverfunktion mit Parametern vom Client auf. Ebenso kann eine Serverfunktion einen Wert als Parameter an einen Erfolgs-Handler zurückgeben.
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 ebenfalls als Parameter zulässig. Es muss jedoch der einzige Parameter der Funktion sein und ist nicht als Rückgabewert zulässig. Anfragen schlagen fehl, wenn Sie versuchen, ein Date-Objekt, eine Function, ein DOM-Element außer einem form-Element 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 und nicht definierte Felder in Arrays werden zu null.
Beachten Sie, dass ein an den Server übergebenes Objekt zu einer Kopie des Originals wird. Wenn eine Serverfunktion ein Objekt empfängt und seine Eigenschaften ändert, sind die Eigenschaften auf dem Client nicht betroffen.
Erfolgs-Handler
Da google.script.run-Aufrufe asynchron sind, wird der clientseitige Code in der nächsten Zeile fortgesetzt, ohne auf eine Antwort zu warten. Wenn Sie eine Callback
Funktion angeben möchten, die ausgeführt wird, wenn der Server antwortet, verwenden Sie
withSuccessHandler(function).
Wenn die Serverfunktion einen Wert zurückgibt, übergibt die API diesen Wert als Parameter an die Callback-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. Wenn Sie das Skript autorisieren möchten, führen Sie die Funktion getUnreadEmails einmal manuell über den Script-Editor aus, bevor Sie die Seite laden. Alternativ werden Sie beim
Bereitstellen der Webanwendung zur
Ausführung als „Nutzer, der auf die Webanwendung zugreift“ aufgefordert, die Autorisierung
zu erteilen.
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
Wenn der Server nicht antwortet oder einen Fehler ausgibt,
withFailureHandler(function)
können Sie einen Fehler-Handler angeben, der anstelle eines Erfolgs-Handlers ausgeführt werden soll.
Wenn ein Fehler auftritt, übergibt die API das
Error
Objekt als Argument an den Fehler-Handler.
Wenn Sie keinen Fehler-Handler angeben, werden Fehler standardmäßig in der JavaScript-Konsole protokolliert. Um dies zu überschreiben, 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' throws 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
Wenn Sie denselben Erfolgs- oder Fehler-Handler für mehrere Aufrufe des
Servers verwenden möchten, rufen Sie
withUserObject(object)
auf, um ein Objekt anzugeben, das als zweiter Parameter an den Handler übergeben wird.
Mit diesem „Nutzerobjekt“, das nicht mit der
User Klasse verwechselt werden darf, 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 und DOM-Elemente, ohne die Einschränkungen für Parameter und Rückgabewerte für Serveraufrufe. Nutzerobjekte können keine Objekte sein, die mit dem Operator new erstellt wurden.
In diesem Beispiel wird durch Klicken auf eine der beiden Schaltflächen die Schaltfläche mit einem Wert vom Server aktualisiert, während die andere Schaltfläche unverändert bleibt, obwohl sie einen gemeinsamen Erfolgs-Handler verwenden. Im onclick-Handler bezieht sich das Schlüsselwort 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 Formular zu einem einzelnen Objekt mit Feldnamen als Schlüsseln und Feldwerten als Werten. Die
Werte werden alle in Strings konvertiert, mit Ausnahme der Inhalte von Dateieingabefeldern, die zu Blob Objekten werden.
In diesem Beispiel wird ein Formular einschließlich eines Dateieingabefelds verarbeitet, ohne die Seite neu zu laden. Die Datei wird in Google Drive hochgeladen und dann die URL der Datei auf der clientseitigen Seite ausgegeben. Im onsubmit-Handler bezieht sich das Schlüsselwort this auf das Formular selbst. Beachten Sie, dass beim Laden aller Formulare auf der Seite die Standardaktion zum Senden durch preventFormSubmit deaktiviert wird. Dadurch 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
Sie können sich google.script.run als Builder für einen „Skriptausführer“ vorstellen. Wenn Sie einem Skriptausführer einen Erfolgs-Handler, einen Fehler-Handler oder ein Nutzerobjekt hinzufügen, ändern Sie den vorhandenen Ausführer nicht. Stattdessen erhalten Sie einen neuen Skriptausführer mit neuem Verhalten.
Verwenden Sie eine beliebige Kombination und Reihenfolge von withSuccessHandler, withFailureHandler und withUserObject. Rufen Sie außerdem eine der Änderungsfunktionen für einen Skriptausführer auf, für den bereits ein Wert festgelegt ist. Der neue Wert überschreibt 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 niemals 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 oder Funktionen sehen, die nicht
auf der obersten Ebene des Skripts deklariert sind.
In diesem Beispiel ist die Funktion getBankBalance im Clientcode verfügbar. Ein Nutzer, der Ihren Quellcode untersucht, kann den Namen ermitteln, auch wenn Sie ihn nicht aufrufen. 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>Dialogfelder in Google Workspace-Anwendungen anpassen
Benutzerdefinierte Dialogfelder in Google Docs,
Google Sheets oder Google Formulare können angepasst werden, indem Sie die
google.script.host-Methoden
setWidth(width) oder
setHeight(height) im
clientseitigen Code aufrufen. Wenn Sie die anfängliche Größe eines Dialogfelds festlegen möchten, verwenden Sie die HtmlOutput
Methoden
setWidth(width)
und
setHeight(height).
Beachten Sie, dass Dialogfelder beim Anpassen der Größe nicht im übergeordneten Fenster zentriert werden und dass Seitenleisten nicht angepasst werden können.
Dialogfelder und Seitenleisten in Google Workspace schließen
Wenn Sie den HTML-Dienst verwenden, um ein Dialogfeld oder
Seitenleiste in Google Docs, Google Sheets,
oder Google Formulare anzuzeigen, können Sie die Benutzeroberfläche nicht mit
window.close schließen. Stattdessen müssen Sie
google.script.host.close aufrufen.
Ein Beispiel finden Sie im Abschnitt HTML als Google Workspace
Benutzer
oberfläche bereitstellen.
Browserfokus in Google Workspace verschieben
Wenn Sie den Fokus im Browser des Nutzers von einem Dialogfeld oder einer Seitenleiste zurück zum
Google Docs-, Google Sheets- oder Google Formulare-Editor verschieben möchten, rufen Sie die
Methode
google.script.host.editor.focus auf.
Diese Methode ist besonders nützlich in Kombination mit den Document
Dienstmethoden Document.setCursor(position)
und
Document.setSelection(range).