soiz1 commited on
Commit
e80644a
·
verified ·
1 Parent(s): fb0ef54

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +83 -103
index.html CHANGED
@@ -1,122 +1,102 @@
1
  <!DOCTYPE html>
2
  <html lang="ja">
3
  <head>
4
- <meta charset="UTF-8" />
5
- <title>1ファイル完結 Service Worker + iframe + Blob</title>
 
 
 
 
 
 
 
6
  </head>
7
  <body>
8
- <h1>Service Worker Blob + iframe で1ファイル完結</h1>
9
- <div id="log">Service Worker 状態ログ</div>
10
 
11
- <!-- 1. Service Worker スクリプトをscriptタグに埋める -->
12
- <script type="text/javascript" id="sw-script">
13
- self.addEventListener('fetch', event => {
14
- const { request } = event;
15
- event.respondWith(
16
- fetch(request).then(response => {
17
- const resClone = response.clone();
18
- resClone.text().then(body => {
19
- self.clients.matchAll().then(clients => {
20
- clients.forEach(client => {
21
- client.postMessage({
22
- type: 'fetch-log',
23
- url: request.url,
24
- status: response.status,
25
- body: body.slice(0, 100)
 
 
 
 
 
 
 
 
26
  });
27
- });
28
- });
29
- });
30
- return response;
31
- }).catch(error => {
32
- self.clients.matchAll().then(clients => {
33
- clients.forEach(client => {
34
- client.postMessage({
35
- type: 'fetch-error',
36
- url: request.url,
37
- error: error.toString()
38
- });
39
- });
40
- });
41
- throw error;
42
- })
43
- );
44
- });
45
  </script>
46
 
 
47
  <script>
48
- (async () => {
49
- const log = document.getElementById('log');
50
-
51
- // 2. sw-scriptタグからService Workerコードを取得
52
- const swScript = document.getElementById('sw-script').textContent.trim();
53
-
54
- // 3. iframe用のHTMLをBlob化する
55
- const iframeHtml = `
56
- <!DOCTYPE html>
57
- <html lang="ja">
58
- <head><meta charset="UTF-8"><title>SW iframe</title></head>
59
- <body>
60
- <script>
61
- // Service Worker スクリプトをevalで実行して登録
62
- const swCode = \`${swScript.replace(/`/g, '\\`')}\`;
63
-
64
- // BlobにしてURLを作成
65
- const blob = new Blob([swCode], {type: 'application/javascript'});
66
- const swBlobUrl = URL.createObjectURL(blob);
67
 
68
- navigator.serviceWorker.register(swBlobUrl).then(reg => {
69
- parent.postMessage({type: 'sw-registered'}, '*');
70
- }).catch(err => {
71
- parent.postMessage({type: 'sw-error', error: err.toString()}, '*');
72
- });
73
-
74
- // Service Worker からのメッセージを親に転送
75
- navigator.serviceWorker.addEventListener('message', e => {
76
- parent.postMessage({type: 'sw-message', data: e.data}, '*');
77
- });
78
- <\/script>
79
- </body>
80
- </html>`;
81
-
82
- const blob = new Blob([iframeHtml], { type: 'text/html' });
83
- const iframeUrl = URL.createObjectURL(blob);
84
-
85
- // 4. iframeを作成して読み込む
86
- const iframe = document.createElement('iframe');
87
- iframe.src = iframeUrl;
88
- iframe.style.width = '100%';
89
- iframe.style.height = '200px';
90
- document.body.appendChild(iframe);
91
 
92
- // 5. iframeからのメッセージを受け取り、ログ表示
93
- window.addEventListener('message', (event) => {
94
- if (!event.data) return;
95
- const { type, error, data } = event.data;
96
 
97
- if (type === 'sw-registered') {
98
- log.textContent = '✅ Service Worker 登録成功!通信を監視中...';
99
- } else if (type === 'sw-error') {
100
- log.textContent = '❌ Service Worker 登録失敗: ' + error;
101
- } else if (type === 'sw-message') {
102
- const { url, status, body, error: fetchError } = data;
103
- const div = document.createElement('div');
104
- if (data.type === 'fetch-log') {
105
- div.innerHTML = `✅ ${url} - ${status}<pre>${body}</pre>`;
106
- div.style.color = 'green';
107
- } else if (data.type === 'fetch-error') {
108
- div.innerHTML = `❌ ${url} - エラー: ${fetchError}`;
109
- div.style.color = 'red';
110
- }
111
- document.body.appendChild(div);
112
  }
113
- });
114
 
115
- // 6. iframe内で動くfetchテスト(親で発火してもService Workerが拾う)
116
- fetch('https://jsonplaceholder.typicode.com/posts/1');
117
- fetch('https://httpstat.us/404'); // エラーの例
 
118
 
119
- })();
 
 
 
120
  </script>
121
  </body>
122
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="ja">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <title>1ファイル Service Worker 通信ログ</title>
6
+ <style>
7
+ body { font-family: sans-serif; padding: 1em; }
8
+ #log { margin-top: 1em; font-size: 14px; }
9
+ .success { color: green; margin-bottom: 1em; }
10
+ .error { color: red; margin-bottom: 1em; }
11
+ pre { background: #f9f9f9; padding: 0.5em; border: 1px solid #ccc; }
12
+ </style>
13
  </head>
14
  <body>
15
+ <h1>Service Worker 通信ログ</h1>
16
+ <div id="log">Service Worker を登録中...</div>
17
 
18
+ <!-- Service Worker Script as text -->
19
+ <script id="sw-script" type="javascript/worker">
20
+ self.addEventListener('fetch', event => {
21
+ const { request } = event;
22
+ const url = request.url;
23
+ const method = request.method;
24
+
25
+ event.respondWith(
26
+ fetch(request)
27
+ .then(response => {
28
+ const clone = response.clone();
29
+ clone.text().then(body => {
30
+ self.clients.matchAll().then(clients => {
31
+ clients.forEach(client => {
32
+ client.postMessage({
33
+ type: 'fetch-log',
34
+ method,
35
+ url,
36
+ status: response.status,
37
+ body: body.slice(0, 200)
38
+ });
39
+ });
40
+ });
41
  });
42
+ return response;
43
+ })
44
+ .catch(error => {
45
+ self.clients.matchAll().then(clients => {
46
+ clients.forEach(client => {
47
+ client.postMessage({
48
+ type: 'fetch-error',
49
+ method,
50
+ url,
51
+ error: error.toString()
52
+ });
53
+ });
54
+ });
55
+ throw error;
56
+ })
57
+ );
58
+ });
 
59
  </script>
60
 
61
+ <!-- Register Service Worker from inline script -->
62
  <script>
63
+ const swCode = document.getElementById('sw-script').textContent;
64
+ const blob = new Blob([swCode], { type: 'application/javascript' });
65
+ const swUrl = URL.createObjectURL(blob);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
+ if ('serviceWorker' in navigator) {
68
+ navigator.serviceWorker.register(swUrl).then(() => {
69
+ document.getElementById('log').innerHTML = '✅ Service Worker 登録完了。通信ログを表示します。';
70
+ }).catch(error => {
71
+ document.getElementById('log').innerHTML = '❌ 登録失敗: ' + error.message;
72
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
+ navigator.serviceWorker.addEventListener('message', event => {
75
+ const data = event.data;
76
+ const div = document.createElement('div');
77
+ div.className = data.type === 'fetch-log' ? 'success' : 'error';
78
 
79
+ if (data.type === 'fetch-log') {
80
+ div.innerHTML = `
81
+ ✅ [${data.method}] ${data.url} ${data.status}<br>
82
+ <pre>${data.body}</pre>
83
+ `;
84
+ } else if (data.type === 'fetch-error') {
85
+ div.innerHTML = `
86
+ [${data.method}] ${data.url}<br>
87
+ エラー: ${data.error}
88
+ `;
 
 
 
 
 
89
  }
 
90
 
91
+ document.getElementById('log').appendChild(div);
92
+ });
93
+ }
94
+ </script>
95
 
96
+ <!-- 通信テスト用 -->
97
+ <script>
98
+ fetch('https://jsonplaceholder.typicode.com/posts/1');
99
+ fetch('https://httpstat.us/404'); // エラーを意図的に出す
100
  </script>
101
  </body>
102
  </html>