-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenvironment-detector.html
More file actions
336 lines (302 loc) · 13.8 KB
/
environment-detector.html
File metadata and controls
336 lines (302 loc) · 13.8 KB
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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Environment Detector</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
line-height: 1.6;
}
h1, h2 {
color: #333;
}
.section {
margin-bottom: 30px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
background-color: #f9f9f9;
}
.success {
color: green;
font-weight: bold;
}
.error {
color: red;
font-weight: bold;
}
#externalScriptResult {
padding: 10px;
border: 1px dashed #ccc;
background-color: #f5f5f5;
}
table {
width: 100%;
border-collapse: collapse;
}
table, th, td {
border: 1px solid #ddd;
}
th, td {
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
pre {
background-color: #f5f5f5;
padding: 10px;
border-radius: 5px;
overflow-x: auto;
}
</style>
</head>
<body>
<h1>Environment Detector</h1>
<div class="section">
<h2>Environment Information</h2>
<table id="envInfo">
<tr>
<th>Property</th>
<th>Value</th>
</tr>
</table>
</div>
<div class="section">
<h2>Protocol Restrictions Test</h2>
<p>Testing what's allowed/restricted based on how this page is loaded:</p>
<div id="protocolTests"></div>
</div>
<div class="section">
<h2>External Script Loading</h2>
<p>Attempting to load a script from CDN (lodash):</p>
<div id="externalScriptResult">Loading...</div>
</div>
<div class="section">
<h2>Iframe Test</h2>
<p>Attempting to load example.com in an iframe:</p>
<div id="iframeTest">
<iframe id="testIframe" src="https://example.com" width="100%" height="200" style="border: 1px solid #ddd;"></iframe>
</div>
<div id="iframeResult"></div>
</div>
<div class="section">
<h2>AJAX Request Test</h2>
<p>Attempting to make AJAX requests:</p>
<div id="ajaxResult"></div>
</div>
<div class="section">
<h2>Local Storage Test</h2>
<p>Testing localStorage access:</p>
<div id="localStorageResult"></div>
</div>
<div class="section">
<h2>Summary: File:// Protocol Limitations</h2>
<ul id="limitations">
<li>Loading this page will show the practical limitations in real-time</li>
</ul>
</div>
<script>
// Environment information detection
function detectEnvironment() {
const table = document.getElementById('envInfo');
const envInfo = [
{ property: "Protocol", value: window.location.protocol },
{ property: "Origin", value: window.location.origin || "N/A (likely file://)" },
{ property: "Host", value: window.location.host || "N/A (likely file://)" },
{ property: "Pathname", value: window.location.pathname },
{ property: "Full URL", value: window.location.href },
{ property: "User Agent", value: navigator.userAgent },
{ property: "Platform", value: navigator.platform },
{ property: "Browser Language", value: navigator.language },
{ property: "Screen Resolution", value: `${window.screen.width} x ${window.screen.height}` },
{ property: "Window Size", value: `${window.innerWidth} x ${window.innerHeight}` },
{ property: "Device Pixel Ratio", value: window.devicePixelRatio },
{ property: "Cookies Enabled", value: navigator.cookieEnabled ? "Yes" : "No" },
{ property: "Do Not Track", value: navigator.doNotTrack || "Not specified" },
{ property: "Connection Type", value: navigator.connection ? navigator.connection.effectiveType : "Unknown" }
];
// Browser detection
let browserInfo = "Unknown";
const ua = navigator.userAgent;
if (ua.includes("Firefox")) {
browserInfo = "Firefox";
} else if (ua.includes("Chrome") && !ua.includes("Edg")) {
browserInfo = "Chrome";
} else if (ua.includes("Safari") && !ua.includes("Chrome")) {
browserInfo = "Safari";
} else if (ua.includes("Edg")) {
browserInfo = "Edge";
} else if (ua.includes("MSIE") || ua.includes("Trident/")) {
browserInfo = "Internet Explorer";
}
// OS detection
let osInfo = "Unknown";
if (ua.includes("Windows")) {
osInfo = "Windows";
} else if (ua.includes("Mac")) {
osInfo = "macOS";
} else if (ua.includes("Linux")) {
osInfo = "Linux";
} else if (ua.includes("Android")) {
osInfo = "Android";
} else if (ua.includes("iPhone") || ua.includes("iPad")) {
osInfo = "iOS";
}
envInfo.push({ property: "Browser", value: browserInfo });
envInfo.push({ property: "Operating System", value: osInfo });
// Add to the table
envInfo.forEach(item => {
const row = table.insertRow();
const cell1 = row.insertCell(0);
const cell2 = row.insertCell(1);
cell1.textContent = item.property;
cell2.textContent = item.value;
});
}
// Protocol restrictions test
function testProtocolRestrictions() {
const testsDiv = document.getElementById('protocolTests');
const isFileProtocol = window.location.protocol === 'file:';
const isLocalhost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
const isHTTPS = window.location.protocol === 'https:';
let html = '<ul>';
if (isFileProtocol) {
html += '<li><strong>Loading context:</strong> <span class="error">File:// protocol</span> - Various security restrictions apply</li>';
} else if (isLocalhost) {
html += '<li><strong>Loading context:</strong> <span class="success">Localhost</span> - Some restrictions relaxed</li>';
} else if (isHTTPS) {
html += '<li><strong>Loading context:</strong> <span class="success">HTTPS domain</span> - Full features available</li>';
} else {
html += '<li><strong>Loading context:</strong> <span class="error">HTTP domain</span> - Some modern features restricted</li>';
}
html += '</ul>';
testsDiv.innerHTML = html;
}
// Load external script (CDN)
function testExternalScript() {
const resultDiv = document.getElementById('externalScriptResult');
try {
// Create script element to load lodash
const script = document.createElement('script');
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js';
script.onload = function() {
// Test if lodash loaded successfully
if (typeof _ !== 'undefined') {
const testArray = [1, 2, 3, 4, 5];
const sum = _.sum(testArray);
resultDiv.innerHTML = `<span class="success">External script loaded successfully!</span><br>
Test: Sum of [1,2,3,4,5] using lodash = ${sum}`;
} else {
resultDiv.innerHTML = '<span class="error">Script loaded but library not available</span>';
}
};
script.onerror = function() {
resultDiv.innerHTML = '<span class="error">Failed to load external script. This is common when using file:// protocol due to security restrictions.</span>';
};
document.head.appendChild(script);
} catch (error) {
resultDiv.innerHTML = `<span class="error">Error: ${error.message}</span>`;
}
}
// Test iframe loading
function testIframe() {
const iframe = document.getElementById('testIframe');
const resultDiv = document.getElementById('iframeResult');
iframe.onload = function() {
try {
// Try to access iframe content - will fail due to same-origin policy
const iframeContent = iframe.contentWindow.document.body.innerHTML;
resultDiv.innerHTML = '<span class="success">Successfully accessed iframe content (unusual)!</span>';
} catch (error) {
resultDiv.innerHTML = '<span class="error">Cannot access iframe content due to same-origin policy</span><br>This is normal security behavior for cross-origin iframes.';
}
};
iframe.onerror = function() {
resultDiv.innerHTML = '<span class="error">Failed to load iframe</span>';
};
}
// Test AJAX requests
function testAjax() {
const resultDiv = document.getElementById('ajaxResult');
// Test AJAX to example.com
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(data => {
resultDiv.innerHTML += '<p><span class="success">AJAX to external API successful!</span><br>Response: <pre>' + JSON.stringify(data, null, 2) + '</pre></p>';
})
.catch(error => {
resultDiv.innerHTML += `<p><span class="error">AJAX to external API failed: ${error.message}</span><br>This is expected if using file:// protocol due to CORS restrictions.</p>`;
});
// Test AJAX to local file
fetch('nonexistent-local-file.json')
.then(response => {
if (!response.ok) throw new Error('File not found or access denied');
return response.json();
})
.then(data => {
resultDiv.innerHTML += '<p><span class="success">AJAX to local file successful!</span> (This is unusual)</p>';
})
.catch(error => {
resultDiv.innerHTML += `<p><span class="error">AJAX to local file failed: ${error.message}</span><br>This is expected, especially on file:// protocol due to security restrictions.</p>`;
});
}
// Test localStorage
function testLocalStorage() {
const resultDiv = document.getElementById('localStorageResult');
try {
// Try to use localStorage
localStorage.setItem('test', 'Environment Detector was here');
const retrieved = localStorage.getItem('test');
if (retrieved === 'Environment Detector was here') {
resultDiv.innerHTML = '<span class="success">localStorage works!</span> Test value stored and retrieved successfully.';
} else {
resultDiv.innerHTML = '<span class="error">localStorage partially working - value mismatch</span>';
}
} catch (error) {
resultDiv.innerHTML = `<span class="error">localStorage failed: ${error.message}</span><br>This can happen in private browsing modes or if storage is disabled.`;
}
}
// Generate summary of file:// limitations
function generateLimitations() {
const limitationsUl = document.getElementById('limitations');
limitationsUl.innerHTML = '';
const limitations = [
"AJAX requests to remote servers usually fail due to CORS restrictions",
"AJAX requests to local files usually fail due to security restrictions",
"Some browsers completely block loading external scripts when using file://",
"IndexedDB and some other storage APIs may be restricted",
"Service workers cannot be registered from file:// context",
"WebRTC and some other modern APIs may be limited",
"Cookies may not function properly",
"Some modern features require secure contexts (HTTPS only)",
"console.log and developer tools still work normally",
"Basic JavaScript execution works normally",
"DOM manipulation works normally",
"localStorage often works (browser-dependent)"
];
limitations.forEach(limitation => {
const li = document.createElement('li');
li.textContent = limitation;
limitationsUl.appendChild(li);
});
}
// Run all tests
window.onload = function() {
detectEnvironment();
testProtocolRestrictions();
testExternalScript();
testIframe();
testAjax();
testLocalStorage();
generateLimitations();
};
</script>
</body>
</html>