-
Notifications
You must be signed in to change notification settings - Fork 0
/
integrity-and-preload.html
126 lines (124 loc) · 5.43 KB
/
integrity-and-preload.html
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
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>Demo Page for Subresource Integrity and Preload</title>
<meta name=description content="demo page for Subresource Integrity (SRI) and Preload">
<meta http-equiv=X-UA-Compatible content="IE=Edge">
<meta name=viewport content="width=device-width,initial-scale=1.0">
<meta name=robots content=index,follow>
<link rel=canonical href=https://laysent.github.io/subresource-integrity-demo/integrity-and-preload.html />
<link rel=preload href=./style.css as=style crossorigin=anonymous />
<link rel=preload href=./script.js as=script crossorigin=anonymous />
<link
href=./main.css
rel=stylesheet
integrity="sha512-mbzzgGIjfEC93ZP2SML7m8+qpNxg4KQH5s28RcwDGfgB8mpa9MbIlSg1GDd6IMeHowT1owpRqNnSJK7Feob12g=="
crossorigin=anonymous
/>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-31656866-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-31656866-1');
</script>
</head>
<body>
<main>
<h1>Subresource Integrity and Preload</h1>
<section>
<h2>explaination</h2>
<p>
This demo page is help you understand behavior of <em>preload</em> and <em>integrity</em>
resources.
</p>
<p>
You should be able to use querystring to control whether <em>SRI</em> is provided
in resources.
</p>
<ul>
<li><em>integrity=none</em> to set integrity for neither script nor stylesheet</li>
<li><em>integrity=script</em> to set integrity for only script</li>
<li><em>intergity=style</em> to set integrity for only stylesheet</li>
</ul>
<p>
You should be able to see warning in Chrome's console when <em>preload</em> resources are
not used. This will happen when <em>integrity</em> is provided as attribute in resource.
</p>
<p>
According to <a href=https://github.com/w3c/preload/issues/127>this issue</a>, Chrome is
having difficulty dealing with <em>preload</em> resources loaded with <em>SRI</em>.
To summerize, Chrome compiled preload resource and discard the raw bytes, hence it's not
possible to calculate the hash to validating <em>subresource integrity</em> later when
resource is actually required.
</p>
<p>
Please notice that cache might play a role here. Though Chrome puts warning in console,
it will not re-fetch the content unless cache is disabled in DevTool. The second time,
when content is actually required, browser will simply read it from disk cache.
</p>
<p>
For other browsers, Safari does not have the same issue as Chrome does, Firefox does not
support <em>Preload</em> feature by default. Meanwhile, if enable <em>Preload</em> feature
in Firefox by toggling <em>network.preload</em> in <em>about:config</em>, it will have
same behavior as Chrome.
</p>
</section>
<section>
<h2>Status of resources loading</h2>
<ul id=status-bar>
<li id=style-failed class=failed>Style failed to load</li>
<li id=style-succeeded class=succeeded>Style loaded successfully</li>
<li id=script-failed class=failed>Script failed to load</li>
</ul>
</section>
<section>
<h2>Crossorigin</h2>
<p>
As mentioned in <a href=./integrity.html>previous demo page</a>, <em>SRI</em> comes usually
with cross-domain request and requires to add <em>crossorigin="anonymous"</em>, so that
browser can read the content and calculate hash. When using resource with <em>crossorigin</em>
given, it's also required to provide same <em>crossorigin</em> in <em>preload</em>, otherwise
preloaded resource will be ignored.
</p>
</section>
<section>
<a href=./index.html>Back</a>
</section>
<footer>
© 2018 LaySent.
</footer>
</main>
<script>
var querystring = location.search.substr(1).split('&').reduce((acc, pair) => {
var parts = pair.split('=');
acc[parts[0]] = parts[1];
return acc;
}, { });
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = './style.css';
link.crossOrigin = 'anonymous';
if (querystring.integrity !== 'none' && querystring.integrity !== 'script') {
link.integrity = 'sha512-7z8mwAKsLTdd/Gto8TfFUpcx1F0+HMB2mxZpkthvOs7FAtKzVQiwa7fF48jSv2tk6vYRtgfT3K5l2DOMWrqyRA==';
}
link.onerror = () => {
console.error('failed to load stylesheet');
};
setTimeout(() => document.head.appendChild(link), 2000);
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = './script.js';
script.crossOrigin = 'anonymous';
if (querystring.integrity !== 'none' && querystring.integrity !== 'style') {
script.integrity = 'sha512-zw36VuUy/09iVs2cRYeF80XlEEf0sRRDpBojNYf+3AlG++nhf6UcgWIQXiHKaLkw36VZLqV7nn/OeacCLsjaBA==';
}
script.onerror = () => {
console.error('failed to load script');
};
setTimeout(() => document.body.appendChild(script), 2500);
</script>
</body>
</html>