Chrome - Fetch API cannot load file. How to workaround? Chrome - Fetch API cannot load file. How to workaround? google-chrome google-chrome

Chrome - Fetch API cannot load file. How to workaround?


For chrome you still need --allow-file-access-from-files (and I recommend installing a separate chrome and using it solely for these projects to stay secure), but just shim fetch() for XMLHttpRequest for file:// requests:

if (/^file:\/\/\//.test(location.href)) {    let path = './';    let orig = fetch;    window.fetch = (resource) => ((/^[^/:]*:/.test(resource)) ?        orig(resource) :        new Promise(function(resolve, reject) {            let request = new XMLHttpRequest();            let fail = (error) => {reject(error)};            ['error', 'abort'].forEach((event) => { request.addEventListener(event, fail); });            let pull = (expected) => (new Promise((resolve, reject) => {                if (                    request.responseType == expected ||                    (expected == 'text' && !request.responseType)                )                    resolve(request.response);                else                    reject(request.responseType);            }));            request.addEventListener('load', () => (resolve({                arrayBuffer : () => (pull('arraybuffer')),                blob        : () => (pull('blob')),                text        : () => (pull('text')),                json        : () => (pull('json'))            })));            request.open('GET', resource.replace(/^\//, path));            request.send();        })    );}

This shim will;

  • only activate for html files opened locally (outer if statement),
  • call the normal fetch() for any url that doesn't specify protocol (and thus non-file:// requests), and
  • will replace absolute paths (/root/bob.html) with ones relative to the current path (since that would dangerously evaluate to C:\ or equivalent)

Set path to something else if your index.html isn't actually at the root for the project.
If you need support for init, or anything other than text(), you'll need to add it.
Explicit file:// requests wont be fulfilled, that's on purpose, but if you really do know what you're doing, you'll know how to make this work for you, and if you don't you shouldn't.


The following is useful if you're going to be doing this for multiple files. Swap out './' for document.currentScript.getAttribute('data-root'). Now you can put that snippet into its own file, say filesystemHelper.js, and call like so in the various files:

<script src="../filesystemHelper.js" data-root="../"></script>

Pretty snazzy.