Last active
October 22, 2024 03:33
-
-
Save rpggio/5f521e1f15f969529f4fe506fc0d1c0a to your computer and use it in GitHub Desktop.
Automatic retry for iframe loading (workaround for Google Doc Viewer 204 issue)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function GoogleDocFrame({ url }: { url: string }) { | |
const frameRef = useRef<HTMLIFrameElement>(null) | |
const viewerUrl = `https://docs.google.com/viewer?embedded=true&url=${url}` | |
let cancel: () => void | undefined | |
useEffect(() => { | |
cancel = setFrameSrcWithRetry(frameRef.current!, viewerUrl, true) | |
// unmount | |
return () => { | |
if (cancel) { | |
cancel() | |
} | |
} | |
}, [url]) | |
return <iframe ref={frameRef} /> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Set src for an iframe. If the iframe does not load, try setting src again to | |
* force reload. Repeat for given number of times. | |
* This can be used as a workaround for Google doc viewer 204 issue: https://tinyurl.com/y7zx253q | |
* Viewer URL pattern: [https://docs.google.com/viewer?embedded=true&url=PUBLIC_URL] | |
* @param iframe | |
* @param src | |
* @param maxRetries - Max number of time to try frame reload | |
* @param initialDelayMs - Initial delay time to use. Exponential easing is used | |
* for additional cycles. | |
*/ | |
export default function setFrameSrcWithRetry( | |
iframe: HTMLIFrameElement, | |
src: string, | |
maxRetries = 4, | |
initialDelayMs = 3000) { | |
console.log('setting frame source') | |
let retriesLeft = maxRetries | |
let loaded = false | |
let timeoutRef: any = null | |
let delayMs = initialDelayMs | |
const cancel = () => { | |
retriesLeft = 0 | |
if (timeoutRef) { | |
clearTimeout(timeoutRef) | |
} | |
} | |
const setRetry = () => { | |
setTimeout(() => { | |
if (!loaded && retriesLeft-- > 0) { | |
log.info('forcing iframe refresh') | |
iframe.src = src | |
setRetry() | |
delayMs *= 1.5 | |
} | |
}, delayMs) | |
} | |
iframe.onload = () => { | |
loaded = true | |
cancel() | |
} | |
iframe.src = src | |
setRetry() | |
return cancel | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think server overload will result in 204 respond, as this is an undocumented feature from Google, we can't expect that much :(
If your pdf support CORS, I'd say using pdf.js for a better viewer