Cordova-plugin-ionic-webview: Failed to load resource: unsupported URL only on iOS

Created on 10 Jan 2019  路  26Comments  路  Source: ionic-team/cordova-plugin-ionic-webview

Hi, i'm using this plugin version 2.3.1
and i getting this error
Failed to load resource: unsupported URL
unsafe:ionic-asset:///var/mobile/Containers/Data/Application/4554564-564554-5646545/tmp/cdv_photo_014.jpg

only on iOS platform. please help me to fix this
config.xml

"name="WKPort" value="8080""
name="UseScheme" value="true"
allow-intent href="itms:"
allow-intent href="itms-apps:
"

Most helpful comment

I encountered the same error and I solved it with

import { DomSanitizer } from '@angular/platform-browser';
import { WebView } from '@ionic-native/ionic-webview/ngx';

constructor ( private webview: WebView, private sanitizer: DomSanitizer)

this.sanitizer.bypassSecurityTrustResourceUrl( this.webview.convertFileSrc( imgPath ) );

Thanks to @prescindivel

this.sanitize.bypassSecurityTrustResourceUrl(window.Ionic.WebView.convertFileSrc(path))

this solved to me

All 26 comments

Problem is the UseScheme. When it is set to false, the url will be file:///var/mobile.... to load those files on both iOS 10 and 11. When set to true, the url I mentioned works on iOS 10 but not on iOS 11 as it replaced file:// with ionic-asset:// and it is seen as unsecure. Maybe whitelisting it is the solution?

Noticed that ionic-asset:// was missing but even when adding

it didnt solve it yet.

Did you find a solution to this

Did you find a solution to this

No, so I had to change UseScheme to false so it would use the old webserver. (Although security advice is not to do this). The advantage of changing it back is that you get the same behavior on iOS 10 and iOS 11 while if you set UseScheme to true, you get different link on both iOS versions. But it can help till someone solves the ionic-asset issue.

Yea I didn't find any solution to this either so just waiting

I also got the problem when UseScheme is set to true ( cordova-plugin-ionic-webview v2.3.1) with a custom port. I've tried everything to whitelist but i always got this on IOS11:
Refused to load
unsafe:ionic://app/img/def_picture2.png because it does not appear in the img-src directive of the Content Security Policy.
Does anyone managed to configure allow-navigation and Content-Security-Policy to allow those files ? I don't want to go back to UseScheme set to false because of the security issue.

<meta http-equiv="Content-Security-Policy" content="default-src 'self' ionic: data: gap: https://ssl.gstatic.com 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; media-src 'self'; img-src ionic: 'unsafe-inline'">

Worked for me

@Bramzor Actually u r right. UseScheme=true is not working for iOS.

Finally fixed the issue by setting preferences to the iOS
preference name="WKPort" value="8080"
preference name="UseScheme" value="false"

specifically set theses preference for iOS.

Thanks everyone!

@RameshkrishnanV why are you closing since Ionic explicitly told to use UseSheme = true and a different port for security ?

@geshub Hey ionic web view by default it takes useScheme as false. so its ok to use it in preferences
see this
https://github.com/ionic-team/cordova-plugin-ionic-webview/blob/2.x/README.md

UseScheme = false is indeed a BAD idea but its the only way to work around the issue today. But we need to keep this issue open to track as it still requires a fix. Usescheme = false is a security risk today.

this.sanitize.bypassSecurityTrustResourceUrl(window.Ionic.WebView.convertFileSrc(path))

this solved to me

this.sanitize.bypassSecurityTrustResourceUrl(window.Ionic.WebView.convertFileSrc(path))

this solved to me

Where are you setting that?

this.sanitize.bypassSecurityTrustResourceUrl(window.Ionic.WebView.convertFileSrc(path))
this solved to me

Where are you setting that?

you need to set up a custom pipe for this importing dom sanitizer from angular platform browser

I encountered the same error and I solved it with

import { DomSanitizer } from '@angular/platform-browser';
import { WebView } from '@ionic-native/ionic-webview/ngx';

constructor ( private webview: WebView, private sanitizer: DomSanitizer)

this.sanitizer.bypassSecurityTrustResourceUrl( this.webview.convertFileSrc( imgPath ) );

Thanks to @prescindivel

this.sanitize.bypassSecurityTrustResourceUrl(window.Ionic.WebView.convertFileSrc(path))

this solved to me

Encontrei o mesmo erro e resolvi-o com

import { DomSanitizer } from '@angular/platform-browser';
import { WebView } from '@ionic-native/ionic-webview/ngx';

constructor ( private webview: WebView, private sanitizer: DomSanitizer)

this.sanitizer.bypassSecurityTrustResourceUrl( this.webview.convertFileSrc( imgPath ) );

Gra莽as a @prescindivel

this.sanitize.bypassSecurityTrustResourceUrl(window.Ionic.WebView.convertFileSrc(path))
isso resolveu para mim

Can you show your html ?

Here is my HTML code

<ion-content>
            <img class="picture" [src]="image.path">
            <p class="t-primary t-90 center" (click)="selectImage()">Ajouter une
                photo</p>
</ion-content>

And my code to take a picture

image: {
        name: string;
        path: string | SafeResourceUrl;
        filePath: string;
    };

constructor( 
                 private actionSheetController: ActionSheetController,
                 private camera: Camera,
                 private platform: Platform,
                 private filePath: FilePath,
                 private file: File,
                 private storage: Storage,
                 private webview: WebView,
                 private sanitizer: DomSanitizer, ) {
    }

pathForImage( img ) {
        if ( img === null ) {
            return '';
        } else {
            if ( this.platform.is( 'android' ) ) {
                return this.sanitizer.sanitize( SecurityContext.RESOURCE_URL,
                                                this.sanitizer.bypassSecurityTrustResourceUrl( this.webview.convertFileSrc( img ) ) );
            } else {
                return this.sanitizer.bypassSecurityTrustResourceUrl( this.webview.convertFileSrc( img ) );
            }
        }
    }

    async selectImage() {
        const actionSheet = await this.actionSheetController.create( {
                                                                         header: 'Select Image source',
                                                                         buttons: [
                                                                             {
                                                                                 text: 'Galerie ',
                                                                                 handler: () => {
                                                                                     this.takePicture( this.camera.PictureSourceType.PHOTOLIBRARY );
                                                                                 },
                                                                             },
                                                                             {
                                                                                 text: 'Appareil Photo',
                                                                                 handler: () => {
                                                                                     this.takePicture( this.camera.PictureSourceType.CAMERA );
                                                                                 },
                                                                             },
                                                                             {
                                                                                 text: 'Annuler',
                                                                                 role: 'cancel',
                                                                             },
                                                                         ],
                                                                     } );
        await actionSheet.present();
    }

    takePicture( sourceType: PictureSourceType ) {
        const options: CameraOptions = {
            quality: 40,
            sourceType,
            encodingType: this.camera.EncodingType.JPEG,
            saveToPhotoAlbum: false,
            correctOrientation: true,
            mediaType: this.camera.MediaType.PICTURE,
            targetHeight: 1000,
            targetWidth: 1000
        };

        this.camera.getPicture( options ).then( imagePath => {
            if ( this.platform.is( 'android' ) && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY ) {
                this.filePath.resolveNativePath( imagePath )
                    .then( filePath => {
                        const correctPath = filePath.substr( 0, filePath.lastIndexOf( '/' ) + 1 );
                        const currentName = imagePath.substring( imagePath.lastIndexOf( '/' ) + 1, imagePath.lastIndexOf( '?' ) );
                        this.copyFileToLocalDir( correctPath, currentName, this.createFileName() );
                    } );
            } else {
                const correctPath = imagePath.substr( 0, imagePath.lastIndexOf( '/' ) + 1 );
                const currentName = imagePath.substr( imagePath.lastIndexOf( '/' ) + 1 );
                this.copyFileToLocalDir( correctPath, currentName, this.createFileName() );
            }
        } );

    }

    createFileName() {
        const d = new Date(),
            n = d.getTime();
        return n + '.jpg';
    }

    copyFileToLocalDir( namePath, currentName, newFileName ) {
        this.file.copyFile( namePath, currentName, this.file.dataDirectory, newFileName ).then( success => {
            this.updateStoredImages( newFileName );
        }, error => {
            this.commonService.toast( 'Erreur pendant le stockage de l\'image' );
        } );
    }

    updateStoredImages( name ) {
        const filePath = this.file.dataDirectory + name;
        const resPath = this.pathForImage( filePath );
        this.image = {
            name,
            path: resPath,
            filePath,
        };
    }

path

Tanks :3

What is your error?

What is your error?

he is don麓t load image in ios 麓-麓

What is your error?

he is don麓t load image in ios 麓-麓

Can you send your HTML5 and TS code

This is my code for getPicture

 this.camera.getPicture( options ).then( imagePath => {
            if ( this.platform.is( 'android' ) && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY ) {
                this.filePath.resolveNativePath( imagePath )
                    .then( filePath => {
                        const correctPath = filePath.substr( 0, filePath.lastIndexOf( '/' ) + 1 );
                        const currentName = imagePath.substring( imagePath.lastIndexOf( '/' ) + 1, imagePath.lastIndexOf( '?' ) );
                        this.copyFileToLocalDir( correctPath, currentName, this.createFileName() );
                    } );
            } else {
                const correctPath = imagePath.substr( 0, imagePath.lastIndexOf( '/' ) + 1 );
                const currentName = imagePath.substr( imagePath.lastIndexOf( '/' ) + 1 );
                this.copyFileToLocalDir( correctPath, currentName, this.createFileName() );
            }
        } );

You can see that I am changing image path and after I use
this.sanitizer.bypassSecurityTrustResourceUrl( this.webview.convertFileSrc( img ) ); to display the image

What is your error?

he is don麓t load image in ios 麓-麓

Can you send your HTML5 and TS code

This is my code for getPicture

 this.camera.getPicture( options ).then( imagePath => {
            if ( this.platform.is( 'android' ) && sourceType === this.camera.PictureSourceType.PHOTOLIBRARY ) {
                this.filePath.resolveNativePath( imagePath )
                    .then( filePath => {
                        const correctPath = filePath.substr( 0, filePath.lastIndexOf( '/' ) + 1 );
                        const currentName = imagePath.substring( imagePath.lastIndexOf( '/' ) + 1, imagePath.lastIndexOf( '?' ) );
                        this.copyFileToLocalDir( correctPath, currentName, this.createFileName() );
                    } );
            } else {
                const correctPath = imagePath.substr( 0, imagePath.lastIndexOf( '/' ) + 1 );
                const currentName = imagePath.substr( imagePath.lastIndexOf( '/' ) + 1 );
                this.copyFileToLocalDir( correctPath, currentName, this.createFileName() );
            }
        } );

You can see that I am changing image path and after I use
this.sanitizer.bypassSecurityTrustResourceUrl( this.webview.convertFileSrc( img ) ); to display the image

Thanks, you , you helped me much

hey this work for me!

if(this.platform.is('ios')){
              imgPath = this.domSanitizer.bypassSecurityTrustResourceUrl((<any>window).Ionic.WebView.convertFileSrc(mediaUri));
       imgPath = urlnorm.changingThisBreaksApplicationSecurity.replace("ionic://localhost", "");
}else{
   imgPath = (<any>window).Ionic.WebView.convertFileSrc(mediaUri);
  }

If anyone from ionic 1 wants the solution to this issue, please use this stackoverflow post to fix it.
https://stackoverflow.com/a/30034955

Just place these two line of code in angular.config:
var imgSrcSanitizationWhitelist = /^\s*(https?|ftp|file|ionic):|data:image\//; $compileProvider.imgSrcSanitizationWhitelist(imgSrcSanitizationWhitelist);

100% working solution
ionic webview >= 4

this.profileImgSrc = this.sanitizer.bypassSecurityTrustResourceUrl(this.webview.convertFileSrc(imagePath));

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lincolnthree picture lincolnthree  路  7Comments

paulstelzer picture paulstelzer  路  8Comments

begbeder picture begbeder  路  5Comments

alexverbitsky picture alexverbitsky  路  3Comments

50l3r picture 50l3r  路  7Comments