Subresource Integrity and Fetch
explaination
By default, browser only support integrity for script and stylesheet. However, fetch can provides option integrity as well, which makes it possible to use this feature for other resources, such as image in this demo page.
In this demo, it uses fetch to download an image resource with integrity option provided. The browser will validate after resource is being downloaded. When succeed, image will be shown, otherwise an error will be catched and app can do further steps (for example, load a backup resource from own server).
- correct-integrity=true to set correct hash in integrity.
- correct-integrity=false to set incorrect hash in integrity.
code example
Following is an example written using React. Image will be loaded with integrity validation. Loading component is used when still fetching the resource.
import React from 'react';
function getFetch(src, integrity) {
return fetch(src, { integrity, mode: 'cors' })
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob));
};
const ImageComponent =
/**
* React.memo is used to ensure that
* request will be fetched once only.
*/
React.memo(({ src, integrity, alt, ...rest }) => {
/**
* Use React.lazy with React.Suspense
* to display loading effect when still
* fetching the resource.
*/
const Component = React.lazy(
() => getFetch(src, integrity)
.then(
url => ({
default: (props) => (
React.useEffect(() => () => {
URL.revokeObjectURL(url);
}, []);
<img src={url} alt={props.alt} {...props} />
),
}),
error => ({
default: () => (
<div>Error: {error.toString()}</div>
);
}),
),
);
return <Component alt={alt} {...rest} />;
});
const Image = ({ src, integrity, alt, ...rest }) => {
return (
<React.Suspense fallback={<div>loading...</div>}>
<ImageComponent
src={src}
integrity={integrity}
alt={alt}
{...rest}
/>
</React.Suspense>
);
};
export default Image;
drawback
fetch does not have the same request priority as image or other resources. Meanwhile, browser will not share cache when resource is being used again from a native approach, such as an <img> tag.