3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GASでアプリケーションを作成する際のフォーマット

Last updated at Posted at 2021-08-05

GASのアプリケーションを作成する際に

  • リンククリックでの画面遷移
  • ボタンをクリックでの画面遷移
    を作成するのにかなりの時間を費やしました。

doPostで受け取るとCORSエラーやsameoriginで下記のようなエラーがでてきます。

Access to XMLHttpRequest at 'https://script.google.com/macros/s/********/exec' from origin 'https://www.bugbugnow.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Refused to display 'https://script.google.com/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.

これを回避するためにdoGetでやると良いという記事はすぐにみつかりましたが、doGetにしてもlinkとボタンのどちらも入れるとなぜかエラーが出てきたりしました。

トライ&エラーをしすぎて、何が原因で何を変えたから回避できたのかもはやわからなくなりましたが、今後はこれをフォーマットにしたいと思います。

実装内容

初期画面

リンクとボタンを並べただけですが、
こんな画面になります。

2021-08-05_15h52_49.png

フォルダ構成

フォルダ
.
├── main.gs
├── index.html
├── test1.html
├── test2.html
└── test3.html

遷移先のHTML

test1~3
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h1>test1</h1> <!-- 1をファイル番号と同じ番号にしておく -->
  </body>
</html>

初回表示のHTML

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <!-- jquery -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
  <h2>本番</h2>
  <a href="https://script.google.com/a/macros/{アカウント}/s/***********/exec?file=test1"></a>
  <a href="https://script.google.com/a/macros/{アカウント}/s/***********/exec?filw=test2""></a>

  <h2>テスト</h2>
  <a href="https://script.google.com/a/macros/{アカウント}/s//***********//dev?file=test1">test1へ</a>
  <a href="https://script.google.com/a/macros/{アカウント}/s//***********//dev?file=test2">test2へ</a>
  <button id="btn">test3へ</button>

  <script>
    function callAppsScript(file, params='') {
      var request = {'file': file, 'params': params};
      $.ajax({
        type:"get",
        url: 'https://script.google.com/a/macros/{アカウント}/s//***********//dev', //テスト用
        // url: 'https://script.google.com/a/macros/{アカウント}/s/***********/exec', //本番用
        data: request,
        dataType: "jsonp",
        success: function(data) {
          $('html').html(data.html); //読み込んだファイルとHTMLの内容を置き換える
        }
      }).fail(function(jqXHR, textStatus, errorThrown ) {
        console.log("XMLHttpRequest : " + jqXHR.status + "\ntextStatus     : " + textStatus + "\nerrorThrown    : " + errorThrown.message);
      });
    }

    $('#btn').on('click', () => {
      // alert('clicked');
      callAppsScript('test3'); //読み込みたいファイルを選択
    });


  </script>
</body>
</html>

開発途中だとデプロイをテストで発行されるURLを使った方が、
反映が楽で良いです。

callAppScript()関数の1つ目の引数で、次に呼び出したいファイルを入れています。

GAS

main.gs
function doGet(e) {

  const params = e.parameter;
  const file = params.file;

  // 初回にindexの内容を表示
  if(!file) {
    const htmlOutput = HtmlService.createTemplateFromFile('index').evaluate();

    htmlOutput
      .setTitle('index')
      .addMetaTag('viewport', 'width=device-width, initial-scale=1');

    return htmlOutput;
  }

  const callback = params.callback;

  // リンククリック時に実行
  if(!callback) {
    const htmlOutput = HtmlService.createTemplateFromFile(file).evaluate();
    htmlOutput
      .setTitle(file)
      .addMetaTag('viewport', 'width=device-width, initial-scale=1');

    return htmlOutput;
  }

  // ボタンクリック時に実行
  if(callback) {
    const htmlOutput = HtmlService.createTemplateFromFile(file).evaluate().getContent();

    const responseText = callback + '(' + JSON.stringify({'html': htmlOutput}) + ')';
    const output = ContentService.createTextOutput();

    output.setMimeType(ContentService.MimeType.JAVASCRIPT);
    output.setContent(responseText);
    return output;
  }
}

遷移先にデータを渡す方法

htmlの遷移先のファイルを下記のように変更します。

text1.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h1>test1</h1>
  </body>
</html>

<script>

  function init(data) {
    alert(data.params);
  }

</script>

これでinit関数を作成しておきます。
ここに立ち上がり時に下記のようになるようにGASでコードを追加します。

text1.html(GASでこの状態にする)
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h1>test1</h1>
  </body>
</html>

<script>
  function init(data) {
    alert(data.params);
  }
</script>

<script>
  init({data}); //valueにはその時に渡したい内容を入れておく
</script>

こうしておくと立ち上がり時にinit関数が引数を持った状態で実行されます。
そのためにmain.gsを下記の様に変更します。

main.gs
function doGet(e) {

  const params = e.parameter;
  const file = params.file;

  // 初回にindexの内容を表示
  if(!file) {
    const htmlOutput = HtmlService.createTemplateFromFile('index').evaluate();

    htmlOutput
      .setTitle('index')
      .addMetaTag('viewport', 'width=device-width, initial-scale=1');

    return htmlOutput;
  }

  const callback = params.callback;

  // リンククリック時に実行
  if(!callback) {
    let htmlOutput = HtmlService.createTemplateFromFile(file).evaluate().getContent();

    htmlOutput += '\n<script>\n';
    htmlOutput += 'init(' + JSON.stringify({params: 'GASからJSへデータをパス'}) + ');\n';
    htmlOutput += '</script>';

    htmlOutput = HtmlService.createTemplate(htmlOutput).evaluate();

    htmlOutput
      .setTitle(file)
      .addMetaTag('viewport', 'width=device-width, initial-scale=1');

    return htmlOutput;
  }

  // ボタンクリック時に実行
  if(callback) {
    let htmlOutput = HtmlService.createTemplateFromFile(file).evaluate().getContent();

    htmlOutput += '\n<script>\n';
    htmlOutput += 'init(' + JSON.stringify({params: params.params}) + ');\n';
    htmlOutput += '</script>';

    const responseText = callback + '(' + JSON.stringify({'html': htmlOutput}) + ')';
    const output = ContentService.createTextOutput();

    output.setMimeType(ContentService.MimeType.JAVASCRIPT);
    output.setContent(responseText);
    return output;
  }
}
  1. getCotent()でHTMLの文字列を取得
  2. init(params)のデータが入った関数を作成
  3. createTemplate()でhtmlを読み込んでevaluateで評価

というような形に変更しています。

参考記事

GASの関数を実行可能APIじゃない方法で実行する
Passing data to html service
Google Apps ScriptのHTML Serviceで擬似的に画面遷移

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?