Usługa HTML: komunikacja z funkcjami serwera

Metoda google.script.run jest asynchroniczna interfejs API JavaScript po stronie klienta, który umożliwia stronom usługi HTML wywoływanie po stronie serwera. funkcji Apps Script. Poniższy przykład pokazuje najbardziej podstawowe funkcje z google.script.runwywoływanie funkcji na serwerze za pomocą JavaScriptu po stronie klienta.

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>

Jeśli wdrożysz ten skrypt jako aplikację internetową i otworzysz jego adres URL, nie zobaczysz ale jeśli wyświetlisz dzienniki, zobaczysz, że funkcja serwera Zadzwoniono do: doSomething().

Wywołania po stronie klienta do funkcji po stronie serwera są asynchroniczne: po żądań, aby serwer uruchomił funkcję doSomething(), przeglądarka kontynuuje do następnego wiersza kodu, nie czekając na odpowiedź. Oznacza to, że te wywołania funkcji serwera mogą nie być wykonywane w oczekiwanej kolejności. Jeśli masz dwóch wywołań funkcji jednocześnie, nie można określić, która z nich najpierw uruchom wynik może być inny przy każdym wczytaniu strony. W takim przypadku moduły obsługi sukcesów i niepowodzeń, pozwalają sterować przepływem kodu.

Interfejs API google.script.run umożliwia 10 równoczesnych wywołań funkcji serwera. Jeśli po 11. wywołaniu, gdy nadal będzie działać 10, funkcja serwera do momentu zwolnienia jednego z 10 miejsc. W praktyce rzadko nad tym ograniczeniem, zwłaszcza że większość przeglądarek już teraz liczba żądań równoczesnych do tego samego serwera przy liczbie mniejszej niż 10. Na przykład w przeglądarce Firefox limit wynosi 6. Większość przeglądarek w podobny sposób opóźnia nadmierne obciążenie do momentu zrealizowania jednego z istniejących żądań.

Parametry i zwracane wartości

Możesz wywołać funkcję serwera za pomocą parametrów z klienta. Podobnie funkcja serwera może zwrócić wartość klientowi jako parametr przekazywany do moduł obsługi sukcesu.

Parametry prawne i zwracane wartości to podstawowe elementy JavaScriptu, np. Number, Boolean, String i null oraz obiekty i tablice JavaScript, które są złożone z elementów podstawowych, obiektów i tablic. element form na stronie; jest także legalny jako parametr, ale musi być jedynym parametrem funkcji, nie jest legalną wartością zwracaną. Żądania kończą się niepowodzeniem, jeśli spróbujesz Date, Function, element DOM inny niż form lub inny zabroniony typ, w tym niedozwolone typy w obiektach lub tablicach. Obiekty, które tworzą Odwołania cykliczne również będą nieudane, a niezdefiniowane pola w tablicach zostaną null

Zauważ, że obiekt przekazywany do serwera staje się kopią oryginału. Jeśli zwraca obiekt i zmienia jego właściwości, nie wpłynie to na klienta.

Moduły obsługi sukcesu

Ponieważ kod po stronie klienta przechodzi do następnego wiersza bez oczekiwania na serwer. do wykonania. withSuccessHandler(function) pozwala na określenie funkcji wywołania zwrotnego po stronie klienta, która ma być wykonywana, gdy serwer odpowiada. Jeśli funkcja serwera zwraca wartość, interfejs API przekazuje ją do nowej funkcji jako parametru.

Poniższy przykład pokazuje alert przeglądarki, gdy serwer odpowiada. Notatka że ten przykładowy kod wymaga autoryzacji, ponieważ funkcja po stronie serwera jest uzyskiwania dostępu do konta Gmail. Najprostszym sposobem autoryzacji skryptu jest uruchomienie funkcję getUnreadEmails() ręcznie w edytorze skryptów przed wczytanie strony. Jeśli wdrożyć aplikację internetową, jako „użytkownik uzyskujący dostęp do aplikacji internetowej”. W takim przypadku pojawi się prośba o autoryzację.

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>

Moduły obsługi błędów

Jeśli serwer nie odpowie lub zgłosi błąd, withFailureHandler(function) pozwala na określenie modułu obsługi błędów zamiast modułu skutecznego, ze znakiem Error obiekt (jeśli istnieje) przekazany jako argument.

Jeśli nie określisz modułu obsługi błędów, domyślnie błędy będą rejestrowane w w konsoli JavaScript. Aby to zmienić, wywołaj funkcję withFailureHandler(null) lub podaj który nie robi nic złego.

Składnia modułów obsługi błędów jest prawie identyczna jak w przypadku z przykładami.

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>

Obiekty użytkownika

Możesz używać tego samego modułu obsługi powodzenia lub niepowodzenia w wielu wywołaniach funkcji serwer, wywołując withUserObject(object) , aby określić obiekt, który będzie przekazywany do modułu jako drugi parametr. Ten „obiekt użytkownika” – nie należy mylić z User – pozwalają Ci odpowiedzieć na w którym klient skontaktował się z serwerem. Obiekty użytkowników nie są wysyłanych do serwera, mogą to być niemal wszystkie elementy, w tym funkcje, DOM elementów itd., bez ograniczeń w zakresie parametrów i zwracanych wartości. dla wywołań serwera. Obiekty użytkownika nie mogą być jednak obiektami utworzonymi za pomocą funkcji new.

W tym przykładzie kliknięcie dowolnego z tych przycisków spowoduje zaktualizowanie na przycisku z serwera, pozostawiając drugi przycisk bez zmian, nawet jeśli korzystać z jednego modułu obsługi. W module obsługi onclick słowo kluczowe this odnosi się do elementu 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>

Formularze

Jeśli wywołujesz funkcję serwera z parametrem form, formularz staje się pojedynczym obiektem z nazwami pól jako kluczami, a wartościami pól jako wartościami. wszystkie wartości są konwertowane na ciągi tekstowe, z wyjątkiem zawartości pola file-input , które stają się obiektami Blob.

W tym przykładzie przetwarzamy formularz, w tym pole wejściowe pliku, bez ponownego wczytywania stronę; przesyła plik na Dysk Google, a następnie wyświetla adres URL na stronie klienta. W module obsługi onsubmit słowo kluczowe this dotyczy samego formularza. Po wczytaniu wszystkich formularzy na stronie domyślna funkcja przesyłania wyłączona przez użytkownika preventFormSubmit. Zapobiega to przekierowania na stronę o niedokładnym adresie URL w przypadku wystąpienia wyjątku.

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>

Uruchomione skrypty

Element google.script.run możesz traktować jako narzędzie do tworzenia skryptów uruchamiających skrypt. Jeśli dodać do programu uruchamiającego skrypt moduł obsługi powodzenia, moduł obsługi błędów lub obiekt użytkownika, nie zmieniają obecnego biegu, wyświetli się nowy kreator, z nowym sposobem działania.

Możesz użyć dowolnej kombinacji tych atrybutów i dowolnej kolejności: withSuccessHandler(), withFailureHandler() i withUserObject(). Możesz też wywołać dowolną w narzędziu uruchamiającym skrypt, który ma już ustawioną wartość. Nowy po prostu zastępuje poprzednią wartość.

W tym przykładzie ustawiany jest typowy moduł obsługi błędów dla wszystkich 3 wywołań serwera, ale dla dwóch oddzielne moduły obsługi sukcesu:

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

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

Funkcje prywatne

Funkcje serwera, których nazwy kończą się podkreśleniem, są uznawane za prywatne. Te funkcje nie mogą być wywoływane przez funkcję google.script, a ich nazwy nigdy nie są wysyłane do klienta. Dzięki temu możesz ich używać do ukrywania szczegółów implementacji, które nie muszą być poufne na serwerze. google.script również nie widzi funkcje w bibliotekach i funkcjach, które nie są zadeklarowaną na najwyższym poziomie skryptu.

W tym przykładzie funkcja getBankBalance() jest dostępna w interfejsie klienta kod; użytkownik przeglądający kod źródłowy może poznać jego nazwę, nawet jeśli Nie nazywaj tego. Jednak funkcje deepSecret_() i obj.objectMethod() są całkowicie niewidoczne dla: do klienta.

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>

Zmiana rozmiaru okien Google Workspace w aplikacjach

niestandardowych okien dialogowych w Dokumentach, Arkuszach lub Rozmiar formularzy można zmienić, wywołując Metody: google.script.host setWidth(width) lub setHeight(height) in po stronie klienta. (Aby ustawić początkowy rozmiar okna, użyj funkcji HtmlOutput metod setWidth(width) oraz setHeight(height). Po zmianie rozmiaru okna dialogowe nie są wyśrodkowane w oknie nadrzędnym. nie można zmienić rozmiaru pasków bocznych.

Zamykam okna dialogowe i paski boczne w Google Workspace

Jeśli używasz usługi HTML do wyświetlania okna dialogowego lub paska bocznego w Dokumentach, Arkuszach lub Formularze, nie można zamknąć interfejsu, wywołując funkcję window.close(). Zamiast tego: musi wywołać google.script.host.close() Zobacz na przykład sekcję poświęconą obsługując kod HTML jako Google Workspace interfejs.

Przenoszenie fokusu przeglądarki za Google Workspace

Aby przenieść zaznaczenie w przeglądarce użytkownika z okna lub paska bocznego z powrotem na W Dokumentach, Arkuszach lub Formularzach Google wystarczy wywołać metodę google.script.host.editor.focus() Metoda ta jest szczególnie przydatna w połączeniu z Metody usługi dokumentów Document.setCursor(position). oraz Document.setSelection(range)