Ionic 3:警告:清理不安全的URL值

时间:2018-05-30 12:34:57

标签: ios angularjs cordova ionic3

我正试图用离子3 App for iOS中的tesseract OCR引擎拍照并进行分析。我试图在iPhone 8 iOS 11.2.6上运行它 不幸的是,拍摄照片后我在Xcode收到错误,但应用崩溃了:

  

NSURLConnection完成错误 - 代码-1002   以及警告:清理不安全的URL值资产 - library://asset/asset.JPG?id = A791150A-3E89-400E-99D3-E7B3A3D888AA& ext = JPG

感谢您的帮助

home.html的

  <h3 *ngIf="debugText">Debug: {{debugText}}</h3>
    <span>{{recognizedText}}</span>
    <!--<img src="assets/img/demo.png" #demoImg class="start-api" />-->
    <img [src]="image" #imageResult />

    <div *ngIf="_ocrIsLoaded && !image">
            <!--<img src="assets/img/Start-arrow.png" #start class="start-arrow" />-->
    </div>

home.ts:

import { Component, ViewChild, ElementRef, NgZone } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Camera } from '@ionic-native/camera';
import { Platform, ActionSheetController, LoadingController } from 'ionic-angular';

import Tesseract from 'tesseract.js';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  @ViewChild('imageResult') private imageResult: ElementRef;
  @ViewChild('demoImg') private demoImg: ElementRef;

  private recognizedText: string;

  image: string = '';
  _zone: any;
  _ocrIsLoaded: boolean = false;

  brightness: number = 12;
  contrast: number = 52;
  unsharpMask: any = { radius: 100, strength: 2 };
  hue: number = -100;
  saturation: number = -100;

  showEditFilters: boolean = false;

  debugText: string = '';

  constructor(
    private camera: Camera,
    public navCtrl: NavController,
    public platform: Platform,
    public loadingCtrl: LoadingController,
    public actionsheetCtrl: ActionSheetController) {

    this._zone = new NgZone({ enableLongStackTrace: false });
  }

  openMenu() {
    if (this._ocrIsLoaded === true) {
      let actionSheet;
      if (!this.image) {
        actionSheet = this.actionsheetCtrl.create({
          title: 'Actions',
          cssClass: 'action-sheets-basic-page',
          buttons: [
            {
              text: 'Random demo',
              icon: !this.platform.is('ios') ? 'shuffle' : null,
              handler: () => {
                this.randomDemo()
              }
            },
            {
              text: 'Take Photo',
              icon: !this.platform.is('ios') ? 'camera' : null,
              handler: () => {
                this.takePicture()
              }
            },
            {
              text: 'Cancel',
              role: 'cancel', // will always sort to be on the bottom
              icon: !this.platform.is('ios') ? 'close' : null,
              handler: () => {
                console.log('Cancel clicked');
              }
            }
          ]
        });
      }
      else {
        actionSheet = this.actionsheetCtrl.create({
          title: 'Actions',
          cssClass: 'action-sheets-basic-page',
          buttons: [
            {
              text: 'Random demo',
              icon: !this.platform.is('ios') ? 'shuffle' : null,
              handler: () => {
                this.randomDemo()
              }
            },
            {
              text: 'Re-Take photo',
              icon: !this.platform.is('ios') ? 'camera' : null,
              handler: () => {
                this.takePicture()
              }
            },
            {
              text: 'Apply filters',
              icon: !this.platform.is('ios') ? 'barcode' : null,
              handler: () => {
                this.filter()
              }
            },
            {
              text: 'Clean filters',
              icon: !this.platform.is('ios') ? 'refresh' : null,
              handler: () => {
                this.restoreImage()
              }
            },
            {
              text: this.showEditFilters == false ? 'Customize filters' : 'Hide customization filters',
              icon: !this.platform.is('ios') ? 'hammer' : null,
              handler: () => {
                this.showEditFilters = this.showEditFilters == false ? true : false;
              }
            },
            {
              text: 'Read image',
              icon: !this.platform.is('ios') ? 'analytics' : null,
              handler: () => {
                this.analyze(this.imageResult.nativeElement.src, false);
              }
            },
            {
              text: 'Cancel',
              role: 'cancel', // will always sort to be on the bottom
              icon: !this.platform.is('ios') ? 'close' : null,
              handler: () => {
                console.log('Cancel clicked');
              }
            }
          ]
        });
      }
      actionSheet.present();
    }
    else {
      alert('OCR API is not loaded');
    }
  }

  restoreImage() {
    if (this.image) {
      this.imageResult.nativeElement.src = this.image;
    }
  }

  takePicture() {
    let loader = this.loadingCtrl.create({
      content: 'Please wait...'
    });
    loader.present();

    // Take a picture saving in device, as jpg and allows edit
    this.camera.getPicture({
      quality: 100,
      destinationType: this.camera.DestinationType.NATIVE_URI,
      encodingType: this.camera.EncodingType.JPEG,
      targetHeight: 1000,
      sourceType: 1,
      allowEdit: true,
      saveToPhotoAlbum: true,
      correctOrientation: true
    }).then((imageURI) => {
      loader.dismissAll();

      this.image = imageURI;
      this.debugText = imageURI;

    }, (err) => {
      //console.log(`ERROR -> ${JSON.stringify(err)}`);
    });
  }

  filter() {
    /// Initialization of glfx.js
    /// is important, to use js memory elements
    /// access to Window element through (<any>window)
    try {
      var canvas = (<any>window).fx.canvas();
    } catch (e) {
      alert(e);
      return;
    }

    /// taken from glfx documentation
    var imageElem = this.imageResult.nativeElement; // another trick is acces to DOM element
    var texture = canvas.texture(imageElem);

    canvas.draw(texture)
      .hueSaturation(this.hue / 100, this.saturation / 100)//grayscale
      .unsharpMask(this.unsharpMask.radius, this.unsharpMask.strength)
      .brightnessContrast(this.brightness / 100, this.contrast / 100)
      .update();

    /// replace image src 
    imageElem.src = canvas.toDataURL('image/png');
  }

  analyze(image, loadAPI) {
    let loader = this.loadingCtrl.create({
      content: 'Please wait...'
    });
    loader.present();

    if (loadAPI == true) {
      this._ocrIsLoaded = false;
    }
    /// Recognize data from image
    Tesseract.recognize(image, {})
      .progress((progress) => {
        this._zone.run(() => {
          loader.setContent(`${progress.status}: ${Math.floor(progress.progress * 100)}%`)
          console.log('progress:', progress);
        })
      })
      .then((tesseractResult) => {
        this._zone.run(() => {
          loader.dismissAll();
          if (loadAPI == true) {
            this._ocrIsLoaded = true;
          }
          console.log('Tesseract result: ');
          console.log(tesseractResult);
          /// Show a result if data isn't initializtion
          if (loadAPI != true) { this.recognizedText = tesseractResult.text; }
        });
      });
  }

  randomDemo() {

  }

  ionViewDidLoad() {
    console.log('loaded')
    this.analyze(this.demoImg.nativeElement.src, true);
  }
}

info.plist中:

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleDisplayName</key>
    <string>Diagnyzer</string>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleIcons</key>
    <dict/>
    <key>CFBundleIcons~ipad</key>
    <dict/>
    <key>CFBundleIdentifier</key>
    <string>io.ionic.diagnyzer</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>0.0.1</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>0.0.1</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSMainNibFile</key>
    <string/>
    <key>NSMainNibFile~ipad</key>
    <string/>
    <key>UISupportedInterfaceOrientations</key>
    <array>
      <string>UIInterfaceOrientationPortrait</string>
      <string>UIInterfaceOrientationLandscapeLeft</string>
      <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
      <string>UIInterfaceOrientationPortrait</string>
      <string>UIInterfaceOrientationLandscapeLeft</string>
      <string>UIInterfaceOrientationPortraitUpsideDown</string>
      <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UIRequiresFullScreen</key>
    <true/>
    <key>NSAppTransportSecurity</key>
    <dict>
      <key>NSExceptionDomains</key>
      <dict>
        <key>ionic.local</key>
        <dict>
          <key>NSExceptionAllowsInsecureHTTPLoads</key>
          <true/>
        </dict>
      </dict>
      <key>NSAllowsArbitraryLoads</key>
      <true/>
    </dict>
    <key>NSCameraUsageDescription</key>
    <string>This app needs camera access</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>This app needs read/write-access photo library access</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string/>
    <key>NSMicrophoneUsageDescription</key>
    <string>This app needs microphone access</string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>This app needs write-access to photo library</string>
  </dict>
</plist>

3 个答案:

答案 0 :(得分:4)

我对Ionic了解不多,但在Angular中加载img会导致出现UnsafeUrl异常。

也许您需要使用Dom Sanitizer

DomSanitizer使用示例:

注射它:

constructor(private sanitizer: DomSanitizer,) {}

使用函数获取img内容:

getImgContent(): SafeUrl {
        return this.sanitizer.bypassSecurityTrustUrl(this.imgFile);
    }

所以你在HTML Part中使用:

<img class="object-img"
                   [src]="getImgContent()">

答案 1 :(得分:1)

回答得有点晚,但是尝试将File Path plugin添加到您的项目中。您可以传递您的URL,插件将对其进行解析。

请注意,此插件仅在Android设备上受支持

答案 2 :(得分:0)

仅输入响应(作为字符串)示例

TS

 let routeImg = (data.base as string);

HTML

<img *ngIf="routeImg "  src="routeImg">