🎉
Google Apps ScriptのWebアプリをiframeに埋め込む方法
埋め込みできない・・・
Google Apps Scriptで作成したWebアプリケーションはデフォルトだとiframeに埋め込むことができません。
これはレスポンスヘッダーのX-Frame-Options
にSAMEORIGIN
が設定されている為です。
この状態だと埋め込みエラーが表示される・・・
setXFrameOptionsModeを設定しよう
HtmlService
のsetXFrameOptionsMode
メソッドにXFrameOptionsMode
を渡すことで、X-Frame-Options
の値を変更できます。
XFrameOptionsMode.ALLOWALL
を指定してみましょう。
function doGet() {
let html = HtmlService
.createHtmlOutputFromFile('index')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
return html;
}
templateを使っている場合もevaluate()
実行後に同様の設定が可能です。
function doGet() {
let template = HtmlService.createTemplateFromFile("index");
template.tite = 'タイトル';
return template
.evaluate()
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
再デプロイとレスポンスヘッダーの確認
再デプロイ後、レスポンスヘッダーを確認するとX-Frame-Options
が無くなっています。
埋め込み再挑戦
このWebアプリを再度iframeで埋め込むと・・・
無事に表示することができました。
SARAHでは一皿に特化したごはん情報の投稿・配信・収集・解析するサービスをtoC,toBと多角的に展開しています。アプリ / Web / SaaS / データサイエンス を最新の環境と技術で広く運用します。 技術スタック詳細はこちら→ stackshare.io/companies/sarah-inc
Discussion
なんか…できません…。
function doGet(e) {
var re = HtmlService.createTemplateFromFile("index");
//メッセージを追加
re.version = "1.20.1";
return re.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME).setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL).addMetaTag("viewport","width=device-width,initial-scale=1").setFaviconUrl("https://upload.wikimedia.org/wikipedia/commons/6/68/Firefox_Developer_Edition_logo%2C_2017.png").addMetaTag("apple-mobile-web-app-capable","yes").addMetaTag("mobile-web-app-capable","yes");
}
iframeのsrcに設定しているURLが「デプロイをテスト」で発行されるテスト用のURLになっていませんか?(末尾がdevで終わる)
本記事の設定を反映させるには正式なデプロイを行い、末尾がexecのURLを使ってみてください。
記事内の表現が分かりづらかったので、追記させていただきました!
ありがとうございます
本記事のおかげで外部親HTMLのiframe内にGASで作成したwebアプリHTMLを追加させることが出来ました!
GAS-webアプリは簡単な発注画面のような作りで
① index.html →
② confirm.html →
③ complete.html
大まかにこのような作り~画面遷移になっています。
GAS-webアプリ単体では動作確認OKなのですが、
iframe内で動作させてみると ① index.html でボタンクリックした時に、
② confirm.html がブラウザ全体で画面遷移してしまい親HTMLから外れてしまいます。
親HTMLはそのままで、iframe内のみで GAS-webアプリの動作を継続させる方法はありますでしょうか?
お役に立てたようで良かったです!
ご質問の件ですが、具体的にどのような方法で画面遷移されてますか?
遷移方法を変えることで、親ウィンドウへの影響を抑えられるかもしれません。
返信ありがとうございます!
GASおじさんのブログ
上記サイトの「発注フォームを作る」を参考に(ほぼ丸々コピペ)で作成しました。doGet(e) と doPost(e) の一部コードは下記の通りです。
function doGet(e) {
const items = getAllRecords('商品');
const template = HtmlService.createTemplateFromFile('index');
template.deployURL = ScriptApp.getService().getUrl();
template.formHTML = getFormHTML(e, items);
const htmlOutput = template.evaluate();
htmlOutput.addMetaTag('viewport', 'width=device-width, initial-scale=1');
htmlOutput.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
return htmlOutput;
}
function doPost(e) {
const items = getAllRecords('商品');
// index.htmlで「確認画面へ」ボタンが押されたらconfirm.htmlへ
if(e.parameter.confirm) {
const template = HtmlService.createTemplateFromFile('confirm');
template.deployURL = ScriptApp.getService().getUrl();
template.confirmHTML = getConfirmHTML(e, items);
const htmlOutput = template.evaluate();
htmlOutput.addMetaTag('viewport', 'width=device-width, initial-scale=1');
htmlOutput.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
return htmlOutput;
}
// confirm.htmlで「発注する」ボタンが押されたらcomplete.htmlへ
if(e.parameter.submit) {
createOrder(e, items);
//updateZaiko(e, items);
sendMail(e, items);
const template = HtmlService.createTemplateFromFile('complete');
template.deployURL = ScriptApp.getService().getUrl();
const htmlOutput = template.evaluate();
htmlOutput.addMetaTag('viewport', 'width=device-width, initial-scale=1');
htmlOutput.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
return htmlOutput;
}
}
doGetのみではなく、doPostにもsetXFrameOptions~を記述すればいいのかな?
と、素人判断で追記していますが希望の動作になりません(iframe内でページ遷移せずに親ページを遷移してしまいます)
そもそも不可能なのか、または何かヒントを頂ければ幸いです!
index.htmlとconfirm.htmlのformタグに、
target="_self"
を追加してみてください!早速追加してみました!
結果は
① index.html →
② confirm.html は iframe内で希望通りに動作しました!(歓喜)
② confirm.html →
③ complete.html は 画面真っ白となりました。
iframe内からではく、GAS‐HTML親ブラウザでテストしても 真っ白となりました。
② confirm.html内の target="_self" を取り除いてみると、元通りに ③ complete.html が正常に表示されました。
最後の ③ complete.html で トップへ戻るリンク<a href=~ にも target="_self" を追加してみてはおりますが、② → ③の時点で真っ白のため試せてはおりません。
なにか足りない部分があるのでしょうか...?
私も同じ症状になることを確認しました。
どうやら2回目の遷移のときにこの事象が起きるようです。
index -> confirm -> conplete だけでなく、
index -> 1回目入力エラー -> 2回目入力エラーでも2回目入力エラーは画面表示されませんでした。
GASでのiframe内のpost遷移になにか問題があるようで、解決方法はまだわかっておりません。
追加の開発が必要になりますが、postで遷移させるのではなく、スクリプトによってSPAライクな動作に変更すれば解決する可能性はあるかと思います。
Lilycat様
事象再現いただきありがとうございました。
SPAライク=単一webページ設計構造のようにということですね(ググってみました)
引き続きいろいろ調べて勉強してみます!