HTML 서비스: 서버 함수와 통신

google.script.run는 비동기식입니다. HTML 서비스 페이지가 서버 측을 호출할 수 있도록 하는 클라이언트 측 JavaScript API Apps Script 함수. 다음 예는 kubectl 명령어 /google.script.run서버에서 함수 호출 클라이언트 측 자바스크립트에서 추출해야 합니다.

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>

이 스크립트를 웹 앱으로 배포하고 URL을 방문하면 로그를 보면 서버 함수가 doSomething()이 호출되었습니다.

서버 측 함수에 대한 클라이언트 측 호출은 비동기식입니다. 브라우저 서버가 doSomething() 함수를 실행하도록 요청하면 브라우저는 계속 바로 다음 코드 줄로 이동하는 것입니다. 다시 말해 서버 함수 호출이 예상대로 실행되지 않을 수 있습니다. 만약 동시에 호출되면 어떤 함수가 실행하고 페이지를 로드할 때마다 결과가 달라질 수 있습니다. 이러한 상황에서는 성공 핸들러실패 핸들러 코드 흐름을 제어하는 데 도움이 됩니다

google.script.run API는 서버 함수를 동시에 10회 호출할 수 있습니다. 만약 10이 실행 중인 상태에서 11번째 호출을 하면 서버 함수가 10자리 중 한 명이 자리를 비울 때까지 지연됩니다. 실제로는 Cloud Storage에 특히 대부분의 브라우저는 이미 동일한 서버에 대한 동시 요청 수를 10개 미만으로 설정해야 합니다. 예를 들어 Firefox에서는 6으로 제한됩니다. 대부분의 브라우저는 이와 유사하게 초과 기존 요청 중 하나가 완료될 때까지 요청이 중지됩니다.

매개변수 및 반환 값

클라이언트에서 매개변수를 사용하여 서버 함수를 호출할 수 있습니다. 마찬가지로 서버 함수는 success 핸들러를 만듭니다.

유효한 매개변수와 반환 값은 Number와 같은 JavaScript 프리미티브입니다. Boolean, String 또는 null뿐만 아니라 원시, 객체 및 배열로 구성됩니다. 페이지 내 form 요소 도 매개변수로 사용할 수 있지만 함수의 유일한 매개변수여야 합니다. 반환 값으로 합법적이 아닙니다. Date, Function, form 외의 DOM 요소 또는 기타 금지된 유형 객체나 배열 내에 금지된 유형을 포함하는 것도 있습니다. 객체를 생성하는 순환 참조도 실패하고 배열 내의 정의되지 않은 필드는 null

서버에 전달된 객체는 원본의 사본이 됩니다. 만약 서버 함수가 객체를 수신하고 그 속성을 변경하면 클라이언트가 영향을 받지 않습니다

성공 핸들러

클라이언트 측 코드는 서버를 기다리지 않고 다음 줄로 계속 진행하기 때문입니다. 완료하려면 withSuccessHandler(function) 를 사용하면 서버가 콜백이 발생할 때 실행할 클라이언트 측 콜백 함수를 지정할 수 있습니다. 응답합니다. 서버 함수가 값을 반환하는 경우 API는 값을 새 함수를 매개변수로 전달합니다.

다음 예는 서버가 응답할 때 브라우저 알림을 표시합니다. 참고 서버 측 함수가 Gmail 계정에 액세스 스크립트를 승인하는 가장 간단한 방법은 getUnreadEmails() 함수를 수동으로 페이지를 로드합니다. 또는 웹 앱을 배포할 때 '웹 앱에 액세스하는 사용자'로 실행합니다. 이 경우 승인하라는 메시지가 표시됩니다.

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>

실패 핸들러

서버가 응답하지 않거나 오류가 발생하면 withFailureHandler(function) 을 사용하면 성공 핸들러 대신 실패 핸들러를 지정할 수 있습니다. Error 객체 (있는 경우)를 인수로 전달합니다.

기본적으로 실패 핸들러를 지정하지 않으면 실패가 JavaScript 콘솔 이를 재정의하려면 withFailureHandler(null)를 호출하거나 다음을 제공합니다. 아무것도 하지 않는 오류 핸들러입니다.

실패 핸들러의 구문은 성공 핸들러와 거의 동일합니다. 보여 드리겠습니다.

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>

사용자 객체

다음과 같이 여러 호출에 동일한 성공 또는 실패 핸들러를 재사용할 수 있습니다. kubectl 명령어 withUserObject(object) 를 사용하여 핸들러에 두 번째 매개변수로 전달할 객체를 지정합니다. 이러한 '사용자 객체'는 User 클래스: 확인할 수 있습니다 사용자 객체는 서버 측에 전송되면 함수, DOM 등 거의 모든 것이 될 수 있습니다. 요소 등)을 포함할 수 있습니다. 서버 호출에 사용됩니다 하지만 사용자 객체는 new 연산자.

이 예에서 두 버튼 중 하나를 클릭하면 버튼이 다른 버튼은 변경하지 않고 그대로 두더라도 하나의 성공 핸들러를 공유합니다. onclick 핸들러 내에서 키워드 this 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>

양식

form 요소를 매개변수로 사용하여 서버 함수를 호출하는 경우 는 필드 이름을 키로, 필드 값을 값으로 갖는 단일 객체가 됩니다. 이 파일 입력의 내용을 제외하고 값은 모두 문자열로 변환됩니다. 필드로 대체되며 Blob 객체가 됩니다.

이 예에서는 새로고침하지 않고 파일 입력 필드가 포함된 양식을 처리합니다. 페이지 Google Drive에 파일을 업로드한 다음 파일을 찾습니다. onsubmit 핸들러 내에서 키워드 this 양식 자체를 나타냅니다. 페이지의 모든 양식을 로드하면 preventFormSubmit에 의해 기본 제출 작업이 사용 중지됩니다. 이렇게 하면 잘못된 URL로 리디렉션되지 않도록 할 수 있습니다.

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>

스크립트 실행기

google.script.run를 '스크립트 실행기'의 빌더로 생각하면 됩니다. 만약 스크립트 실행기에 성공 핸들러, 실패 핸들러, 사용자 객체를 추가하면 기존 실행기를 변경하지 않습니다 대신 새 스크립트 실행기가 반환되며 적용할 수 있습니다.

withSuccessHandler()를 원하는 대로 조합하여 사용할 수 있습니다. withFailureHandler(), withUserObject() 또한 이미 값이 설정된 스크립트 실행기에서 함수 수정 새로운 값은 이전 값을 재정의합니다.

이 예에서는 세 가지 서버 호출 모두에 대해 공통 실패 핸들러를 설정하지만 별도의 성공 핸들러:

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

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

비공개 함수

이름이 밑줄로 끝나는 서버 함수는 비공개로 간주됩니다. 이러한 함수는 google.script로 호출할 수 없으며 이름은 클라이언트로 전송됩니다 따라서 이러한 메서드를 사용하여 서버에서 비밀로 유지해야 합니다 google.script님도 볼 수 없습니다. 라이브러리 내의 함수와 스크립트의 최상위 수준에서 선언됩니다.

이 예시에서는 getBankBalance() 함수를 클라이언트에서 사용할 수 있습니다. 코드; 소스 코드를 검사하는 사용자는 다른 사람이 그렇게 부르지 마세요. 그러나 deepSecret_()obj.objectMethod() 함수는 있습니다

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>

애플리케이션의 Google Workspace 대화상자 크기 조절

Google Docs, Sheets 또는 Google Slides의 맞춤 대화상자 양식의 크기는 google.script.host 메서드 setWidth(width) 또는 setHeight(height)인치 클라이언트 측 코드를 사용합니다. (대화상자의 초기 크기를 설정하려면 HtmlOutput 방법 setWidth(width)setHeight(height) 참조) 크기가 조절될 때 대화상자는 상위 창에서 다시 중앙에 배치되지 않으며 사이드바의 크기를 조절할 수 없습니다.

Google Workspace의 대화상자 및 사이드바 닫기

HTML 서비스를 사용하여 Google Docs, Sheets 또는 Google Drive의 대화상자 또는 사이드바 Forms에서는 window.close()를 호출하여 인터페이스를 닫을 수 없습니다. 대신 를 호출해야 합니다 google.script.host.close() 예를 보려면 HTML을 사용자 인터페이스로 Google Workspace 제공합니다.

Google Workspace에서 브라우저 포커스 이동 중

사용자의 브라우저에서 대화상자나 사이드바에서 포커스를 다시 Google 문서, 스프레드시트 또는 양식 편집기에서는 google.script.host.editor.focus() 이 방법을 문서 서비스 메서드 Document.setCursor(position)Document.setSelection(range)