こんにちは、中山です(写真は私ではありません)。
写真と同様、既に絶滅してしまったかもしれませんが、以前は META 要素を用いて Set-Cookie を実行する Web アプリケーションが存在しました。
そこで、今更ですが META 要素 + Set-Cookie について考察してみます。
なお調査に利用したブラウザは以下の通りです。
(iOS と Android の標準ブラウザについてはまたの機会に)
- IE 11.0.46
- Firefox 55.0.3
- Chrome 61.0.3163.91
HTML5 仕様の確認
HTML5 仕様 によれば META 要素での Set-Cookie は non-conforming となっています。
(なので、これから開発する Web アプリケーションでの利用はやめておきましょう)
Cookie setter (http-equiv="set-cookie")
This pragma sets an HTTP cookie.
It is non-conforming.
Real HTTP headers should be used instead.
動作は以下の通りです。
1. If the meta element has no content attribute, or if that attribute's value is the empty string, then abort these steps.
2. Obtain the storage mutex.
3. Act as if receiving a set-cookie-string for the document's address via a "non-HTTP" API, consisting of the value of the element's content attribute encoded as UTF-8.
HTTP(Set-Cookie Header)経由ではなく、実質的には document.cookie への書き込みと同様に振舞うべし、と規定されていますね。
各ブラウザの動作
三通りの動作を確認してみたいと思います。
まずは静的な META 要素での Set-Cookie が動作するか否か(#1)。
1 2 3 4 5 6 7 8 9 10 11 |
<head> <meta http-equiv='Set-Cookie' content='KEY=INIT'> </head> <script> (function() { /* 確認 */ window.setTimeout(function() { alert(document.cookie); }, 1000); })(); </script> |
次に content 属性を JavaScript で変更した場合、変更が反映されるか否か(#2)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<head> <meta http-equiv='Set-Cookie' content='KEY=INIT'> </head> <script> (function(in_key, in_value) { /* content 属性の変更 */ var meta = document.getElementsByTagName('META').item(0); meta.setAttribute('content', in_key + '=' + in_value); /* 確認 */ window.setTimeout(function() { alert(document.cookie); }, 1000); })('KEY', 'UPDATE'); </script> |
最後に META 要素(Set-Cookie を実行する)を動的に DOM に追加した場合、cookie が書き込まれるか否か(#3)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<script> (function(in_key, in_value) { /* HEAD + META 要素の追加 */ var meta = document.createElement('META'); meta.setAttribute('http-equiv', 'Set-Cookie'); meta.setAttribute('content', in_key + '=' + in_value); var head = document.createElement('HEAD'); head.appendChild(meta); var target = document.getElementsByTagName('SCRIPT').item(0); target.parentNode.insertBefore(head, target); /* 確認 */ window.setTimeout(function() { alert(document.cookie); }, 1000); })('KEY', 'UPDATE'); </script> |
動作結果は以下の通りです。
HTML5 仕様では non-conforming にも関わらず Chrome の実装は細やかですね。
蛇足
静的な META 要素での Set-Cookie は主要ブラウザで動作することが確認できましたが、将来にわたり動作保証されるわけではありません。
なので、今後利用されることもなさそうですが、ふと JavaScript が使えない AMP で Parasite Cookie の仕込みに使えないだろうか !? と思いましたが(未調査です)、JavaScript が使えないなら仕込んでも読めないので無意味ですね。
ちなみに AMP HTML では http-equiv は利用できるようです。
meta
The http-equiv attribute may be used for specific allowable values; see the AMP validator specification for details.
現場からのレポートは以上となります。