Fetch API cannot load file:///android_asset/www/xx/xxx.json. URL scheme "file" is not supported

Viewed 20410

Using cordova build Android app, and add cordova hot code push plugin to make app update automatically, and using Fetch API to load JSON files which located in current project directory, the problem is when update the app, any JSON files cannot be reload,and throw the error

Fetch API cannot load file:///android_asset/www/xx/xxx.json. URL scheme "file" is not supported.

How to solve this Fecth error in Android app? Or is there any plugin that need add to my cordova project?

4 Answers

I had this same problem, using fetch() in Android (using Cordova) uses the file:// protocol, because of using relative URLs to fetch the resources in the Cordova app in Android, and that gives the error.

My problem was resolved by a combination of Jan's answer and the following page from the MDN web docs: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data

In my case it had to do with the fact that using fetch to retrieve an audio file, I would be able to call arrayBuffer() on the response, but not when using the example fetchLocal() function that Jan links to.

The trick was needing to set the responseType on the XHR object.

My fetchLocal function looks like this:

function fetchLocal(url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest
        xhr.onload = function () {
            resolve(new Response(xhr.response, { status: xhr.status }))
        }
        xhr.onerror = function () {
            reject(new TypeError('Local request failed'))
        }
        xhr.open('GET', url)
        xhr.responseType = "arraybuffer";
        xhr.send(null)
    })
};

The thing that solved it for me was adding this line:

xhr.responseType = "arraybuffer";

I used the code below to sidestep a similar issue with fetch(). I didn't want to use the code from the link in Jan's answer.

function fetchLocalResource(url) {        
    const req = new XMLHttpRequest();    
    req.onload = function() {
        const text = req.responseText;  
        // Do something with text...
    };    
    req.open('GET', url);
    req.send();
}

And with axios:

const blob = await axios.get(url, { responseType: 'blob'}).then(resp => resp.data)
Related