[追記]スクリプトでスクリプトを停止させることの難しさ。
「サイト上で実行されるプログラムについて同意を確認するためのプログラム」という記事で、MutationObserverを使ってscriptタグがDOMに追加させるタイミングでremoveを行うという力業を試してみたのですが、どうにも完全に実行を停止するのは難しいようです。
もともと、本来はheadタグ直下で実行すべきコードを記事文中内で実行しているため、記事以前に記述されているscriptに関しては実行を止めることができていなかったのですが、ほかにもasync属性が設定されているスクリプトに関してはこの方法では実行を止めることはできないようです。
また、一度ページが表示されるとキャッシュが残るため、2回目にページを表示した際に正しく動作しないようです。
サードパーティのスクリプトをフックして実行を制御するのはなかなかに難問でした。
[追記]検証ページつくってみました。
※リンク先の検証ページに飛ぶ前に開発者ツールのコンソールを開いておくと手間が一つ減ります。
検証ページサンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
<!DOCTYPE html> <html lang="jp"> <head> <script type="text/javascript"> window.alert("このページはJavaScriptの実行をJavaScriptで制御する検証ページです。"); const observer = new MutationObserver(mutations => { mutations.forEach(({ addedNodes }) => { addedNodes.forEach(node => { if(node.nodeType === 1 && node.tagName === 'SCRIPT') { const src = node.src || '' const type = node.type; let script = ""; if(src){ script = src; }else{ script = node.innerHTML; } let check = window.confirm("以下のプログラムの実行を許可しますか?n"+script); console.log("ダイアログ戻り値:"+check); if(check){ //console.log("run", script); }else{ console.log("以下のスクリプトを削除しました", script); node.remove(); } } }) }) }); observer.observe(document.documentElement, { childList: true, subtree: true }); </script> </head> <body> <h1>スクリプト制御検証ページ</h1> <p>スクリプトの実行をスクリプトで制御し閲覧者が、実行の許可・不許可を選択できるようにするデモです</p> <p>インラインスクリプト、外部スクリプト、それぞれ同期/非同期が指定された4つのスクリプトと、Google アドセンス(同期/非同期)、Google アナリティクスのスクリプトが設置してあります。</p> <p>スクリプトが承認された場合は、開発者ツールのコンソールに実行結果が、スクリプトが拒否された場合は、同じく開発者ツールのコンソールに「削除しました」と表示されます</p> <script> console.log("%c%s", "color: red; background: yellow; font-size: 24px;", "同期インラインスクリプトが実行されました")</script> <script async> console.log("%c%s", "color: red; background: yellow; font-size: 24px;", "非同期インラインスクリプトが実行されました")</script> <script src="script1.js"></script> <script async src="script2.js"></script> <!-- Google アドセンス 同期 --> <script type="text/javascript"> console.log("%c%s", "color: red; background: yellow; font-size: 24px;", "同期Googleアドセンスコードが実行されました"); google_ad_client = "ca-pub-4060928622734418"; google_ad_slot = "3545706206"; google_ad_width = 336; google_ad_height = 280; </script> <script type="text/javascript" src="//pagead2.googlesyndication.com/pagead/show_ads.js"> </script> <!-- Google アドセンス 非同期 --> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-4060928622734418" data-ad-slot="3545706206"></ins> <script> console.log("%c%s", "color: red; background: yellow; font-size: 24px;", "非同期Googleアドセンスコードが実行されました"); (adsbygoogle = window.adsbygoogle || []).push({}); </script> <!-- Global アナリティクス--> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-27276322-1"></script> <script> console.log("%c%s", "color: red; background: yellow; font-size: 24px;", "Googleアナリティクスコードが実行されました"); window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-27276322-1'); </script> </body> </html> |
検証結果
- Chromeは概ね狙い通りに動いている。
- Safariは、アドセンスのコードが「停止」はできるが、「再実行」できないっぽくて「OK」が押されても広告が表示されない。
- Firefoxは、まったく停止できていないので、この方法ではスクリプトを制御できない。
- IE, Edgeは試していない。