Ad

How To Load An Image Into A Canvas Without CORS Issues For Ionic IOS Hybrid App

I want to load images into a canvas that is used for showing custom google map markers. The following code works for browser and Android but not iOS, as the WKWebView does not accept CORS requests for this matter.

let ctx = canvas.getContext('2d');
let img = new Image();
img.crossOrigin = "anonymous";
img.src = url;

img.onload = function () {
    // process and load the image into the canvas map marker
};
img.onerror = function () {
    // handle fallback                    
};

The images have to be loaded from google maps photos api (and other apis that I do not have control on the CORS settings on the servers). This has to be somehow handled in the app.

What possible solutions exist for this matter?

One thing that I found is ionic-image-loader (https://github.com/zyra/ionic-image-loader) that uses ionic native http requests to load and cache images into an img tag. This works from html though, and I need to use it directly in js/ts, which does not seem to be possible.

If I try to load images via ionic http request, even in browser the request is also blocked by CORS, as opposed to loading the image via img tag. Maybe if (somehow) the following header can be set to the ionic http request so that the request looks the same: Sec-Fetch-Mode: no-cors

[WKWebView] Even the local images cannot load this way and it shows: Origin null is not allowed by Access-Control-Allow-Origin (Cannot load image: file:/// ... ) and then it's stuck in a loop trying to load the image.

Ad

Answer

Solved by using a fork of ionic-image-loader preload function with cordova native http, bypassing the webview entirely for the http request and handling the cache manually. This is how the http request is done, working on iOS WKWebView as well:

let options = {
    method: 'get',
    responseType: 'blob',
    data: {},
    headers: {}
};

cordova.plugin.http.sendRequest(url, options, (data: any) => {
    let blob = data.data;
    resolve(blob);
}, (error: any) => {
    console.log(error.status);
    console.log(error.error);
    reject(error.error);
});
Ad
source: stackoverflow.com
Ad