Chrome92からalertやconfirmが動かなくなりました
以前、Chrome83の際には、アップデート後に、Google Apps Scriptでのボタンクリック時にPDFがダウンロードといった事ができなくなり、非常に困った事態になりました。その後、XFrameOptionsModeでの挙動で、Google Apps Scriptの場合にはtarget属性にblankを指定して、対処することが出来ました。
さて、今回、Chrome92では地味ながら、かなり大きな変更があり、Google Apps Scriptでalertやconfirmが利用できなくなりました。Salesforceなどの外部のサービスでも影響が出ているようです。
※2021/08/03 - 今朝再度、確認したらGoogle Apps Scriptでのalert,confirmの挙動ができるようになっていました。修正されたのか?しかし、今後何があるかわからないので、alert,confirm,promptなどのメソッドを使うのは躊躇われる
※現在、稼働してる理由は、Chromeが2022年まで先送りした為のようで。それまでにGAS側が対応しないと再発予定
目次
今回の現象の詳細
現象の概要とサンプル
下記のiframe内に、xframeoptionsmodeにてGASアプリを表示させていますが、ボタンをクリックしてalertを表示するコードを仕込んであっても、何も無反応です。単体で直接表示させた場合でも同様の挙動です。
これはxframeoptionsmodeを使用していなくても同様です。サンプルファイルはこちらです。
図:クリックしても無反応
ソースコード
GAS側コード
1 2 3 4 5 6 7 8 9 |
//ウェブアプリケーションでグラフを表示 function doGet() { var html = HtmlService.createHtmlOutputFromFile('index') .setSandboxMode(HtmlService.SandboxMode.IFRAME) .setTitle('Chrome92テスト') .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL); return html; } |
HTML側コード
1 2 3 4 5 6 7 8 9 10 11 |
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <button class="tomato" type="button" onclick="alert('test')"> テスト </button> </body> </html> |
- こちらが直リンクになりますが、同様に無反応です
- 上記のHTMLのみ、ファイルにして実行する場合は問題なく動作する(クロスオリジンでもiframe使用でもない為)
Issue Trackerによると
Issue Trackerにも早速、色々と投稿されています。そもそも、この問題は、iframeを使った場合のクロスオリジンに於ける、alert表示やconfirm表示が問題視されてるものであって、通常のHTMLでのalertをブロックするのが目的ではないものの、そもそもGoogle Apps Scriptでのウェブアプリは、iframeを使ったSandbox環境であるため、同一オリジンであっても、ブロックされます。
前回も同じような問題で、結局はChrome側がallow=downloadを、Google Apps Scriptの場合にはXFrameOptionsModeをつけた場合には付与するような対処を随分後になってから装備し直してたりします。自身が提供してるサービスにも多大な影響があるにも関わらず、Chromeチームの一存だけで、リリースし様々なウェブサービス(Salesforceなど)にまで影響を与えてるのは、正直今後問題視されるとともに、Google Workspaceの継続利用にも疑問が出てくることになるでしょう(正直言って、傲慢)。
ユーザはChromeを使わない、Google Workspaceを使わないという選択肢がある事をお忘れなく。
原因と対策
原因
今回、Chrome92になってから、こちらにあるように、Chromeでのalertやconfirmについてはセキュリティや同一性の観点から、iframe内からのalertやconfirmの表示をブロックするようにしましたということのようです。クロスオリジンの問題が原点になりますが、そもそも、Google Apps Scriptは単体表示であっても、iframeを利用したSandbox環境であるため、スプレッドシート上であっても、単体表示であっても、alertやconfirmが表示されなくなってしまいました。
Chromeのリリースチームはどうやら、Chrome83の時もそうでしたが、Google Apps ScriptやGoogle Workspaceへの影響というものをまるで考えていないようです。企業としてどうなんでしょうか?なおこの件については事前アナウンスは全くありませんでした。
Developer Toolで表示すると警告表示とともに、以下のようなメッセージが出ます。
A different origin subframe tried to create a JavaScript dialog. This is no longer allowed and was blocked. See https://www.chromestatus.com/feature/5148698084376576 for more details.
図:単体表示でも同様にブロックされる
問題点
他のサービスであったり、自身のドメイン内であれば、Origin-trialのヘッダを利用する方法(Chrome95まで有効)や、postMessageを利用した子iframeから親のウィンドウに対してメッセージを送る方法にて送れますが、Google Apps ScriptのWebアプリの場合はどちらも利用出来ません。
また、alertやconfirm以下のコードは実行されないでストップしてしまうため、特にconfirmやpromptのようなコードの前半でユーザの解答を受け取ってから動作するコードがある場合、ボタンをクリックしても何も発動しない為、本件を知らない人は何が起きてるのかもわからず、ログにもエラーとしては出てこないので(Developer Toolで確認する必要がある)、非エンジニアな現場開発者の場合、詰む可能性があります。
こういう事が続く場合、Google Workspaceの利用自体に疑問を呈して辞めてしまう企業も出かねません。
回避策や解決策
FireFoxを利用する
前回もそうだったのですが、Googleという企業はユーザへの影響を考えずドラスティックに強制的にリリースし、そしてトラブルを起こすことを何度も繰り返しています。今回も、FireFoxの場合影響を受けない為、今後も社内で利用する場合は、Google Chromeでの運用をやめて、FireFoxへ移行してしまうのも良い考えです。EdgeはChromiumベースなのでNGの可能性があります(現時点、v92.0.902では動作しています)。
※しかしFirefoxもいつ実装するかわからないので、いずれにせよGoogle Apps Scriptでは対応がなされるまで、alertやconfirmなどをHTML Serviceで使わないほうが良いでしょう
図:Firefoxでは問題なく利用できる
起動オプションを付けて起動
Chromeには起動オプションが用意されており、Chromeへのショートカットなどがユーザのデスクトップに表示されてると思いますが、これらをショートカットに割り当てておくと良いでしょう。今回のケースを回避する起動オプションは以下のような感じ
1 2 3 4 5 |
//Windowsの場合 chrome.exe --disable-features="SuppressDifferentOriginSubframeJSDialogs" //macOSの場合 /Applications / Google \ Chrome.app/Contents/MacOS/Google \ Chrome --disable-features="SuppressDifferentOriginSubframeJSDialogs" |
chrome.exeにコマンドラインオプションで指定して、ショートカットに保存します。但しこの手法は、このショートカットからの起動にだけ適用されるので、メーラーなどからChromeを呼び出して起動した場合などには適用されないので、使い勝手はよくないです。
図:リンク先のchrome.exeに起動オプションを追加する
jQuery UIやVuetifyに置き換える
現実的な問題として、Chromeを使わないでくださいとは、外部の人に押し付けるわけには行きません。IEの時もそうでしたが、一強支配による傲慢と弊害ですね。ということで、ウェブアプリケーション側で、alertやconfirmなどのポップアップ表示を使わずに、jQuery UIのダイアログであったり、Bootbox.jsを利用した方法、Vuetifyのダイアログやアラートに置き換えるのが懸命でしょう。
図:Bootbox.jsでの実装例
以下は、Vuetifyで実装したサンプルです。ただ、Vuetifyだとちょっとコード量が増えるのと、お手軽ではないので、Bootbox.jsを使った手法が手軽に実装できると思います。
関連リンク
- Intent to Remove: Cross origin subframe JS Dialogs
- CSSフレームワークBootstrapのダイアログを秒速で実装する「bootbox.js」が超便利
- How to make Chrome 92 display alert(), prompt() and confirm() from iframe opened on different subdomain
- Microsoft Edge で Origin Trials を使用する
- Origin Trials - Google
- 【解決済み】Chromeを最新版(92.0.4515.107)にアップデートすると予定の削除、他人の予定の変更ができない
- Feature: Remove alert(), confirm(), and prompt for cross origin iframes
- chrome92にアップデートしたことでconfirm()が動かなくなった
- サテライトオフィス - 障害情報
- 「Google Chrome 92」が正式公開 ~「Chrome Action」を拡充、サイト分離も強化
- Chrome バージョン92以降で出力ボタンが動作しない場合がある事象について
- Salesforce functionality impacted in Chrome 92 after recent change to cross-origin iframe JavaScript dialogs
- Windows10コンピューターでChromeをシークレットモードで常に起動する方法
- Windows の既定のブラウザ設定について
- 既定Webブラウザの設定レジストリ
- Windowsで既定のアプリでの変更が効かないとき
- Google Chrome 92.0.4515.107 バージョンアップ後にポップアップが正常に動作しない
- alert() is dead, long live print()
Chrome, Firefox, Safariで合意が取れておりwahtwgの仕様にも反映されてるので、利用するブラウザに関わらず将来的に動作しなくなりますね
774さん
遅かれ早かれ、iframe内でのalert等の挙動は全ブラウザで使えなくなるので、ちょっとだけウェブアプリ制作の初期ハードルが上がってしまいますが
仕方ないですね。
ただ、Google Apps Scriptのウェブアプリがiframeの中で動いてるということを知らない人が多いので、デバッグ代わりにalertを使ってる人は、地味にハマリポイントになりそうです