Angular iPad上的IndexedDB/PockDB Blobs,Safari 11.3.1
我有一个angular 5.2.9 PWA应用程序,通过PockDB将数据本地存储到IndexedDB,供脱机使用。此应用程序将照片存储为文档中的Blob。我不使用附件。这在Chrome&Edge浏览器和Andriod上都有效,但是Blob不能在iPad上正确存储或加载。iPad正在运行Safari 11.3.1。当这些照片被拍摄时,它们在我的图库中显示得很好。通过PockDB保存和检索后,我得到一个零大小的Blob。我是否缺少Safari/iPad特定的配置或设置Angular iPad上的IndexedDB/PockDB Blobs,Safari 11.3.1,angular,ipad,safari,indexeddb,pouchdb,Angular,Ipad,Safari,Indexeddb,Pouchdb,我有一个angular 5.2.9 PWA应用程序,通过PockDB将数据本地存储到IndexedDB,供脱机使用。此应用程序将照片存储为文档中的Blob。我不使用附件。这在Chrome&Edge浏览器和Andriod上都有效,但是Blob不能在iPad上正确存储或加载。iPad正在运行Safari 11.3.1。当这些照片被拍摄时,它们在我的图库中显示得很好。通过PockDB保存和检索后,我得到一个零大小的Blob。我是否缺少Safari/iPad特定的配置或设置 import { Compo
import { Component, OnInit, Inject } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs';
import { MatDialog, MatDialogRef } from '@angular/material';
import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';
import { ConfigurationService } from '../../service/configuration.service';
import PouchDB from 'pouchdb';
import { Inspection } from '../../model/inspection';
import { PhotoDialogComponent } from './../photo-dialog/photo-dialog.component';
import { InspectionPhoto } from '../../model/inspection-photo';
import { zip } from 'rxjs/observable/zip';
@Component({
selector: 'app-photo-gallery',
templateUrl: './photo-gallery.component.html',
styleUrls: ['./photo-gallery.component.css']
})
export class PhotoGalleryComponent implements OnInit {
photoDialogRef: MatDialogRef<PhotoDialogComponent>;
inspection: Inspection;
photoList: BehaviorSubject<Array<InspectionPhoto>>;
currentUrl: BehaviorSubject<SafeResourceUrl>;
currentIndex: number;
length: number;
rotate: string;
constructor(public config: ConfigurationService,
public dialogRef: MatDialogRef<PhotoDialogComponent>,
public dialog: MatDialog,
public domSanitiser: DomSanitizer) {
this.photoList = new BehaviorSubject<Array<InspectionPhoto>>(new Array<InspectionPhoto>());
this.currentUrl = new BehaviorSubject<string>('');
this.currentIndex = 0;
this.length = 0;
this.rotate = this.config.getRotateImages() ? "rotate90" : "";
}
ngOnInit() {
let db = new PouchDB('inspection-photo');
db.allDocs({include_docs: true})
.then(result => {
return Promise.all(result.rows.map(row => {
let item = new InspectionPhoto();
item = row.doc;
item._id = row.id;
item._rev = row.rev;
return item;
}));
}).then(list => {
this.length = list.length;
this.currentIndex = 0;
this.photoList.next(list);
if(list.length > 0) {
this.getImageUrl(list[0]);
}
})
.catch(err => {
console.log('ngOnInit db error' + err);
alert('ngOnInit db error' + err);
});
}
public getImageUrl(inspectionPhoto: InspectionPhoto): void {
if(inspectionPhoto == undefined
|| inspectionPhoto.Photo == undefined){
return; }
// alert('blob size: ' + inspectionPhoto.Photo.size);
let modified: Date = new Date();
let f:File = new File([inspectionPhoto.Photo],
"image" + this.currentIndex + ".jpg",
{type: "image/jpeg", lastModified: modified.getUTCMilliseconds()}
);
// alert('file: '
// + ' name: ' + f.name
// + ' type: ' + f.type
// + ' size: ' + f.size
// );
let url: string;
try {
url = URL.createObjectURL(f, {oneTimeOnly: true}); //.substring(5);
}
catch (e) {
alert('1:' + (<Error>e).message + (<Error>e).stack);
}
let sanitisedUrl: SafeResourceUrl;
try{
sanitisedUrl = this.domSanitiser.bypassSecurityTrustResourceUrl(url);
}
catch (e) {
alert('2:' + (<Error>e).message);
}
try{
this.currentUrl.next(sanitisedUrl);
}
catch (e) {
alert('3:' + (<Error>e).message);
}
}
public onNext() {
if (this.currentIndex >= this.length - 1) {
this.currentIndex = 0;
} else {
this.currentIndex += 1;
}
this.photoList.subscribe(list => {
// alert('image:' + this.currentIndex);
this.getImageUrl(list[this.currentIndex]);
});
}
public onPrevious() {
if (this.currentIndex <= 0) {
this.currentIndex = this.length - 1;
} else {
this.currentIndex -= 1;
}
this.photoList.subscribe(list => {
// alert('image:' + this.currentIndex);
this.getImageUrl(list[this.currentIndex]);
});
}
OnNewPhoto(): void {
this.photoDialogRef = this.dialog.open(PhotoDialogComponent, {
});
this.photoDialogRef.afterClosed().subscribe((result) => {
if (result) {
let inspectionPhoto = new InspectionPhoto();
inspectionPhoto.InspectionId = this.inspection._id;
inspectionPhoto.WorkOrderId = this.inspection.WorkOrderId;
inspectionPhoto.TaskId = this.inspection.TaskId;
inspectionPhoto.EquipmentId = this.inspection.EquipmentId;
let db = new PouchDB('inspection-photo');
let files: File[] = Array.from(this.photoDialogRef.componentInstance.files);
files.forEach(f => {
// alert('file: '
// + ' name: ' + f.name
// + ' type: ' + f.type
// + ' size: ' + f.size
// );
inspectionPhoto._id = this.config.uniqueID();
inspectionPhoto.Photo = new Blob([f], {type: 'image/jpeg'});
// alert('Blob size: ' + inspectionPhoto.Photo.size);
db.put(inspectionPhoto)
.then(result => {
inspectionPhoto._id = result.id;
inspectionPhoto._rev = result.rev;
// alert('**** saved photo blob size:' + inspectionPhoto.Photo.size);
this.photoList.subscribe(list => {
list.push(inspectionPhoto);
this.length = list.length;
this.currentIndex = this.length - 1;
});
this.getImageUrl(inspectionPhoto);
})
.catch(err => {
console.log('OnNewPhoto db error ' + err);
alert('OnNewPhoto db error ' + err);
});
});
}
this.photoDialogRef = null;
});
}
}
从'@angular/core'导入{Component,OnInit,Inject};
从“rxjs”导入{observeable,BehaviorSubject};
从“@angular/material”导入{MatDialog,MatDialogRef};
从“@angular/platform browser”导入{domsanizer,SafeResourceUrl,SafeUrl};
从“../../service/configuration.service”导入{ConfigurationService};
从“邮袋数据库”导入邮袋数据库;
从“../../model/Inspection”导入{Inspection};
从“/../photo dialog/photo dialog.component”导入{PhotoDialogComponent};
从“../../model/inspection photo”导入{InspectionPhoto};
从'rxjs/observeable/zip'导入{zip};
@组成部分({
选择器:“应用程序照片库”,
templateUrl:'./photo gallery.component.html',
样式URL:['./photo gallery.component.css']
})
导出类PhotoGalleryComponent实现OnInit{
photoDialogRef:MatDialogRef;
检查:检查;
照片列表:行为主体;
currentUrl:BehaviorSubject;
当前索引:编号;
长度:数字;
旋转:字符串;
构造函数(公共配置:ConfigurationService,
公共dialogRef:MatDialogRef,
公共对话:MatDialog,
公共域消毒器:域消毒器){
this.photoList=new BehaviorSubject(new Array());
this.currentUrl=新行为主体(“”);
此.currentIndex=0;
这个长度=0;
this.rotate=this.config.getRotateImages()?“rotate90”:“;
}
恩戈尼尼特(){
设db=新袋db(“检查照片”);
db.allDocs({include_docs:true})
。然后(结果=>{
返回Promise.all(result.rows.map(row=>{
让项目=新检查照片();
item=row.doc;
项目。_id=row.id;
项目.\u版次=第行版次;
退货项目;
}));
})。然后(列表=>{
this.length=list.length;
此.currentIndex=0;
这个。照片列表。下一个(列表);
如果(list.length>0){
这个.getImageUrl(列表[0]);
}
})
.catch(错误=>{
log('ngOnInit db error'+err);
警报(“ngOnInit db错误”+错误);
});
}
公共getImageUrl(检查照片:检查照片):无效{
如果(检查照片==未定义
||inspectionPhoto.Photo==未定义){
返回;}
//警报('blob大小:'+inspectionPhoto.Photo.size);
让修改:日期=新日期();
设f:File=new文件([inspectionPhoto.Photo],
“image”+this.currentIndex+“.jpg”,
{type:“image/jpeg”,lastModified:modified.getutcmillesons()}
);
//警报('文件:'
//+'名称:'+f.name
//+'类型:'+f.type
//+'尺寸:'+f.size
// );
让url:string;
试一试{
url=url.createObjectURL(f,{oneTimeOnly:true});//.substring(5);
}
捕获(e){
警报('1:'+(e).message+(e).stack);
}
让sanitisedUrl:SafeResourceUrl;
试一试{
sanitisedUrl=this.DomainSanitiser.bypassSecurityTrustResourceUrl(url);
}
捕获(e){
警报('2:'+(e).消息);
}
试一试{
this.currentUrl.next(sanitisedUrl);
}
捕获(e){
警报('3:'+(e).消息);
}
}
public onNext(){
如果(this.currentIndex>=this.length-1){
此.currentIndex=0;
}否则{
此.currentIndex+=1;
}
this.photoList.subscribe(列表=>{
//警报('image:'+此.currentIndex);
this.getImageUrl(列出[this.currentIndex]);
});
}
公共服务{
如果(此.currentIndex){
//警报('image:'+此.currentIndex);
this.getImageUrl(列出[this.currentIndex]);
});
}
OnNewPhoto():void{
this.photoDialogRef=this.dialog.open(PhotoDialogComponent{
});
this.photoDialogRef.afterClosed().subscribe((结果)=>{
如果(结果){
让inspectionPhoto=新建inspectionPhoto();
inspectionPhoto.InspectionId=此.inspection.\u id;
inspectionPhoto.WorkOrderId=此.inspection.WorkOrderId;
inspectionPhoto.TaskId=this.inspection.TaskId;
inspectionPhoto.EquipmentId=此.inspection.EquipmentId;
设db=新袋db(“检查照片”);
let files:File[]=Array.from(this.photoDialogRef.componentInstance.files);
files.forEach(f=>{
//警报('文件:'
//+'名称:'+f.name
//+'类型:'+f.type
//+'尺寸:'+f.size
// );
inspectionPhoto._id=this.config.uniqueID();
inspectionPhoto.Photo=newblob([f],{type:'image/jpeg'});
//警报('Blob大小:'+inspectionPhoto.Photo.size);
db.put(检查照片)
。然后(结果=>{
检查照片。\u id=result.id;
检查照片。_rev=result.rev;
//警报('****保存的照片斑点大小:'+inspectionPhoto.photo.size);
this.photoList.subscribe(列表=>{
列表。推送(检查照片);
this.length=list.length;
this.currentIndex=this.length-1;
});
这个.getImageUrl(检查照片);
})
.catch(错误=>{
log('OnNewPhoto数据库错误'+err);
警报(“OnNewPhoto数据库错误”+错误);
});
});
}
this.photoDialogRef=null;
});
}
}
Safari 11上使用Angular 5#766时IndexedDB识别失败…如果您遇到类似问题,这是由于使用Angular在sfari上识别IndexedDB时出现问题,因此PockDB会返回到websql,而websql不会