google.script.run
è un'API JavaScript asincrona lato client che consente alle pagine del servizio HTML di chiamare le funzioni Apps Script lato server. L'esempio seguente mostra la funzionalità più di base
di google.script.run
: l'chiamata di una funzione sul server
da JavaScript lato client.
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>
Se esegui il deployment di questo script come app web e visiti il relativo URL, non vedrai
nulla, ma se visualizzi i log, vedrai che è stata chiamata la funzione del server
doSomething()
.
Le chiamate lato client alle funzioni lato server sono asincrone: dopo che il browser
richiede al server di eseguire la funzione doSomething()
, il browser continua
immediatamente alla riga di codice successiva senza attendere una risposta. Ciò significa
che le chiamate di funzioni del server potrebbero non essere eseguite nell'ordine previsto. Se esegui
due chiamate di funzione contemporaneamente, non è possibile sapere quale funzione verrà
eseguita per prima; il risultato potrebbe variare ogni volta che carichi la pagina. In questa situazione,
i gestori di successo e i gestori di errori
aiutano a controllare il flusso del codice.
L'API google.script.run
consente 10 chiamate simultanee alle funzioni del server. Se
effettui un'undicesima chiamata mentre 10 sono ancora in esecuzione, la funzione del server verrà
ritardata finché uno dei 10 slot non viene liberato. In pratica, raramente dovrai
pensare a questa limitazione, soprattutto perché la maggior parte dei browser limita già
il numero di richieste simultanee allo stesso server a un numero inferiore a 10.
In Firefox, ad esempio, il limite è 6. La maggior parte dei browser ritarda in modo simile le richieste
del server in eccesso fino al completamento di una delle richieste esistenti.
Parametri e valori restituiti
Puoi chiamare una funzione del server con parametri dal client. Analogamente, una funzione server può restituire un valore al client come parametro passato a un gestore di esito positivo.
I parametri e i valori restituiti legali sono primitive JavaScript come Number
,
Boolean
, String
o null
, nonché oggetti e array JavaScript composti da primitive, oggetti e array. Un elemento form
all'interno della pagina
è valido anche come parametro, ma deve essere l'unico parametro della funzione e
non è valido come valore restituito. Le richieste non vanno a buon fine se tenti di trasmettere un
Date
, Function
, elemento DOM diverso da un form
o un altro tipo vietato,
inclusi i tipi vietati all'interno di oggetti o array. Anche gli oggetti che creano riferimenti circolari non andranno a buon fine e i campi non definiti all'interno degli array diventeranno null
.
Tieni presente che un oggetto passato al server diventa una copia dell'originale. Se una funzione del server riceve un oggetto e ne modifica le proprietà, le proprietà del client non vengono interessate.
Gestori di successo
Poiché il codice lato client continua alla riga successiva senza attendere il completamento di una chiamata al server, withSuccessHandler(function)
ti consente di specificare una funzione di callback lato client da eseguire quando il server risponde. Se la funzione del server restituisce un valore, l'API lo passa
alla nuova funzione come parametro.
Il seguente esempio mostra un avviso del browser quando il server risponde. Tieni presente
che questo esempio di codice richiede l'autorizzazione perché la funzione lato server
accede al tuo account Gmail. Il modo più semplice per autorizzare lo script è eseguire
la funzione getUnreadEmails()
manualmente dall'editor di script una volta prima di
caricare la pagina. In alternativa, quando esegui il deployment dell'app web, puoi scegliere di eseguirla come "utente che accede all'app web", nel qual caso ti verrà chiesto di autorizzare l'app quando la carichi.
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>
Gestori degli errori
Nel caso in cui il server non risponda o generi un errore,
withFailureHandler(function)
ti consente di specificare un gestore di errori anziché un gestore di successo, con l'oggetto
Error
(se presente) passato come argomento.
Per impostazione predefinita, se non specifichi un gestore degli errori, gli errori vengono registrati nella
console JavaScript. Per ignorare questo comportamento, chiama withFailureHandler(null)
o fornisci un gestore di errori che non esegue alcuna operazione.
La sintassi dei gestori di errori è quasi identica a quella dei gestori di esito positivo, come mostra questo esempio.
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>
Oggetti utente
Puoi riutilizzare lo stesso gestore di esito positivo o negativo per più chiamate al server chiamando
withUserObject(object)
per specificare un oggetto che verrà passato al gestore come secondo parametro.
Questo "oggetto utente", da non confondere con la classe User
, ti consente di rispondere al contesto in cui il client ha contattato il server. Poiché gli oggetti utente non vengono inviati al server, possono essere quasi qualsiasi cosa, incluse funzioni, elementi DOM e così via, senza le limitazioni relative a parametri e valori restituiti per le chiamate al server. Tuttavia, gli oggetti utente non possono essere oggetti creati con l'operatore new
.
In questo esempio, se fai clic su uno dei due pulsanti, questo viene aggiornato con un valore del server, mentre l'altro pulsante rimane invariato, anche se condividono un gestore di successo. All'interno del gestore onclick
, la parola chiave this
si riferisce a button
stesso.
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>
Moduli
Se chiami una funzione server con un elemento form
come parametro, il modulo
diventa un singolo oggetto con i nomi dei campi come chiavi e i valori dei campi come valori. I
valori vengono tutti convertiti in stringhe, ad eccezione dei contenuti dei campi
di input dei file, che diventano oggetti Blob
.
Questo esempio elabora un modulo, incluso un campo di input file, senza ricaricare
la pagina; carica il file su Google Drive e poi stampa l'URL del
file nella pagina lato client. All'interno del gestore onsubmit
, la parola chiave this
si riferisce al modulo stesso. Tieni presente che al caricamento tutti i moduli della pagina hanno
l'azione di invio predefinita disattivata da preventFormSubmit
. In questo modo, la pagina non viene reindirizzata a un URL errato in caso di eccezione.
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>
Esecutori script
Puoi considerare google.script.run
come un generatore di un "esecutore di script". Se
aggiungi un gestore di successo, un gestore di errori o un oggetto utente a un esecutore di script, non
modifichi l'esecutore esistente. Al contrario, ricevi un nuovo esecutore di script
con un nuovo comportamento.
Puoi utilizzare qualsiasi combinazione e qualsiasi ordine di withSuccessHandler()
,
withFailureHandler()
e withUserObject()
. Puoi anche chiamare una qualsiasi delle
funzioni di modifica su un runner di script a cui è già stato impostato un valore. Il nuovo valore
semplicemente sostituisce il precedente.
Questo esempio imposta un gestore di errori comune per tutte e tre le chiamate al server, ma due gestori di esito positivo separati:
var myRunner = google.script.run.withFailureHandler(onFailure);
var myRunner1 = myRunner.withSuccessHandler(onSuccess);
var myRunner2 = myRunner.withSuccessHandler(onDifferentSuccess);
myRunner1.doSomething();
myRunner1.doSomethingElse();
myRunner2.doSomething();
Funzioni private
Le funzioni del server i cui nomi terminano con un trattino basso sono considerate private.
Queste funzioni non possono essere chiamate da google.script
e i loro nomi non vengono mai
inviati al client. Puoi quindi utilizzarli per nascondere i dettagli di implementazione che
devono essere mantenuti segreti sul server. google.script
non è in grado di visualizzare
le funzioni all'interno delle librerie e le funzioni che non sono
dichiarate a livello principale dello script.
In questo esempio, la funzione getBankBalance()
è disponibile nel codice client; un utente che esamina il codice sorgente può scoprire il suo nome anche se non lo chiami. Tuttavia, le funzioni deepSecret_()
e obj.objectMethod()
sono completamente invisibili al client.
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>
Ridimensionamento delle finestre di dialogo nelle applicazioni Google Workspace
Le finestre di dialogo personalizzate in Documenti, Fogli o Moduli Google possono essere ridimensionate chiamando i metodi
google.script.host
setWidth(width)
o
setHeight(height)
nel
codice lato client. Per impostare le dimensioni iniziali di una finestra di dialogo, utilizza i metodi HtmlOutput
setWidth(width)
e
setHeight(height)
.)
Tieni presente che le finestre di dialogo non vengono ricentrate nella finestra principale quando vengono ridimensionate e non è possibile ridimensionare le barre laterali.
Chiusura di finestre di dialogo e barre laterali in Google Workspace
Se utilizzi il servizio HTML per visualizzare una
finestra di dialogo o una barra laterale in Documenti, Fogli o
Moduli Google, non puoi chiudere l'interfaccia chiamando window.close()
. Devi invece
chiamare
il numero google.script.host.close()
.
Per un esempio, consulta la sezione relativa alla
visualizzazione di HTML come Google Workspace interfaccia utente.
Spostamento dello stato attivo del browser in Google Workspace
Per spostare il focus nel browser dell'utente da una finestra di dialogo o una barra laterale all'editor di Documenti, Fogli o Moduli Google, chiama semplicemente il metodo google.script.host.editor.focus()
.
Questo metodo è particolarmente utile in combinazione con i metodi del
servizio Documenti
Document.setCursor(position)
e
Document.setSelection(range)
.