我正在尝试使用发布请求发送Cordova - camera
插件捕获的图像。
将其发送到Django rest-framework
。它给我错误type is not file
我在.ts
文件中使用的代码:
import {Component, OnInit} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {HttpClient} from '@angular/common/http';
import {HttpHeaders} from '@angular/common/http';
import {Router} from '@angular/router';
import {ActionSheetController} from '@ionic/angular';
import {Camera, CameraOptions} from '@ionic-native/camera/ngx';
@Component({
selector: 'app-add-dress',
templateUrl: './add-dress.page.html',
styleUrls: ['./add-dress.page.scss'],
})
export class AddDressPage implements OnInit {
cats: Observable<any>;
types: Observable<any>;
sizes: Observable<any>;
actions: Observable<any>;
cities: Observable<any>;
pic: any;
img_1: any;
img_2: any;
img_3: any;
title = '';
desc = '';
color = '';
category = '';
type = '';
size = '';
action = '';
price = '';
city = '';
number = '';
CategoryActionSheetOptions: any = {
header: 'Category',
subHeader: 'Select your dress Category'
};
TypeActionSheetOptions: any = {
header: 'Type',
subHeader: 'Select your dress Type'
};
SizeActionSheetOptions: any = {
header: 'Size',
subHeader: 'Select your dress Size'
};
ActionActionSheetOptions: any = {
header: 'Dress Action',
subHeader: 'Dress is for Sale or Rental'
};
CityActionSheetOptions: any = {
header: 'City',
subHeader: 'Select your City'
};
constructor(public httpClient: HttpClient, private router: Router, public actionSheetController: ActionSheetController,
private camera: Camera) {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('username:password')
})
};
this.cats = this.httpClient.get('https://www.fostania.com/api/categories/', httpOptions);
this.cats.subscribe(data => {
this.cats = data;
console.log('my data: ', data);
});
this.types = this.httpClient.get('https://www.fostania.com/api/types/', httpOptions);
this.types.subscribe(data => {
this.types = data;
console.log('my data: ', data);
});
this.sizes = this.httpClient.get('https://www.fostania.com/api/sizes/', httpOptions);
this.sizes.subscribe(data => {
this.sizes = data;
console.log('my data: ', data);
});
this.actions = this.httpClient.get('https://www.fostania.com/api/actions/', httpOptions);
this.actions.subscribe(data => {
this.actions = data;
console.log('my data: ', data);
});
this.cities = this.httpClient.get('https://www.fostania.com/api/cities/', httpOptions);
this.cities.subscribe(data => {
this.cities = data;
console.log('my data: ', data);
});
}
// take Photo
takePhoto(sourceType: number, img_num) {
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true,
sourceType: sourceType,
};
this.camera.getPicture(options).then((imageData) => {
const base64Image = 'data:image/jpeg;base64,' + imageData;
this.pic = base64Image;
if (img_num === 'Image_1') {
const thumb_1 = document.getElementById('thumb_1');
const change_button_1 = document.getElementById('change_button_1');
const add_button_1 = document.getElementById('add_button_1');
thumb_1.hidden = false;
change_button_1.hidden = false;
add_button_1.hidden = true;
this.img_1 = this.pic;
}
if (img_num === 'Image_2') {
const thumb_1 = document.getElementById('thumb_2');
const change_button_2 = document.getElementById('change_button_2');
const add_button_2 = document.getElementById('add_button_2');
thumb_1.hidden = false;
change_button_2.hidden = false;
add_button_2.hidden = true;
this.img_2 = this.pic;
}
if (img_num === 'Image_3') {
const thumb_1 = document.getElementById('thumb_3');
const change_button_3 = document.getElementById('change_button_3');
const add_button_3 = document.getElementById('add_button_3');
thumb_1.hidden = false;
change_button_3.hidden = false;
add_button_3.hidden = true;
this.img_3 = this.pic;
}
}, (err) => {
console.log(err);
});
}
async presentActionSheet(num) {
const actionSheet = await this.actionSheetController.create({
header: 'Add ' + ' ' + num,
mode: 'ios',
buttons: [{
text: 'Take Photo',
icon: 'camera',
handler: () => {
console.log('take photo clicked');
this.takePhoto(1, num);
}
}, {
text: 'Open Gallery',
icon: 'list',
handler: () => {
console.log('open gallery clicked');
this.takePhoto(0, num);
}
}, {
text: 'Cancel',
icon: 'close',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}]
});
await actionSheet.present();
}
get_form_data() {
console.log(this.title);
console.log(this.desc);
console.log(this.color);
console.log(this.category);
console.log(this.type);
console.log(this.size);
console.log(this.action);
console.log(this.price);
console.log(this.city);
console.log(this.number);
console.log(this.img_1);
console.log(this.img_2);
console.log(this.img_3);
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('username:password')
})
};
const request = {
'item_title': this.title,
'item_description': this.desc,
'item_price' : this.price,
'item_price_later': false,
'item_action': this.action,
'item_color': this.color,
'item_category': this.category,
'item_type': this.type,
'item_size': this.size,
'item_city': this.city,
'item_phone': this.number,
'item_image_1': this.img_1,
'item_image_2': this.img_2,
'item_image_3': this.img_3,
'created_by': 7,
};
this.httpClient.post('https://www.fostania.com/api/items/', request, httpOptions)
.subscribe(data => {
console.log(data['_body']);
}, error => {
console.log(error);
});
}
ngOnInit() {
}
}
正如您看到的id所示,有些获取请求从服务器获取数据,我需要在ion-select
文件的某些.html
输入中使用这些请求。这部分效果很好
这是我的.html
文件:
<ion-header>
<ion-toolbar color="medium">
<ion-buttons slot="start">
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title>
<ion-icon name="add"></ion-icon>
Add your dress
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-card mode="ios">
<ion-card-content>
<h2>Add your Dress</h2>
<small>fill the form to add your dress</small>
<br><br>
<h3>Dress Information:</h3>
<ion-item>
<ion-label position="floating" >Title</ion-label>
<ion-input [(ngModel)]="title"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating" >Description</ion-label>
<ion-textarea [(ngModel)]="desc"></ion-textarea>
</ion-item>
<ion-item>
<ion-label position="floating">Color</ion-label>
<ion-input [(ngModel)]="color"></ion-input>
</ion-item>
<br><br>
<ion-item>
<ion-label>Category</ion-label>
<ion-select [interfaceOptions]="CategoryActionSheetOptions" interface="action-sheet"
placeholder="Select One" [(ngModel)]="category">
<ion-select-option *ngFor="let cat of cats" value="{{cat.id}}">{{cat.category_name}}</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Type</ion-label>
<ion-select [interfaceOptions]="TypeActionSheetOptions" interface="action-sheet"
placeholder="Select One" [(ngModel)]="type">
<ion-select-option *ngFor="let type of types" value="{{type.id}}">{{type.type_name}}</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label>Size</ion-label>
<ion-select [interfaceOptions]="SizeActionSheetOptions" interface="action-sheet"
placeholder="Select One" [(ngModel)]="size">
<ion-select-option *ngFor="let size of sizes" value="{{size.id}}">{{size.size_name}}</ion-select-option>
</ion-select>
</ion-item>
<br><br>
<h3>Price Information:</h3>
<ion-item>
<ion-label>Dress is for</ion-label>
<ion-select [interfaceOptions]="ActionActionSheetOptions" interface="action-sheet"
placeholder="Select One" [(ngModel)]="action">
<ion-select-option *ngFor="let action of actions" value="{{action.id}}">{{action.action_name}}</ion-select-option>
</ion-select>
</ion-item>
<ion-item>
<ion-label position="floating">Price</ion-label>
<ion-input type="number" [(ngModel)]="price"></ion-input>
</ion-item>
<br><br>
<h3>Contact Information:</h3>
<ion-item>
<ion-label>City</ion-label>
<ion-select [interfaceOptions]="CityActionSheetOptions" interface="action-sheet"
placeholder="Select One" [(ngModel)]="city">
<ion-select-option *ngFor="let city of cities" value="{{city.id}}">{{city.city_name}}</ion-select-option>
</ion-select>
</ion-item>
<br>
<ion-item>
<ion-label position="floating">Phone Number</ion-label>
<ion-input type="number" [(ngModel)]="number"></ion-input>
</ion-item>
<br><br>
<h3>Dress Images:</h3>
<ion-item>
<ion-thumbnail id="thumb_1" hidden>
<img src="{{img_1}}">
</ion-thumbnail>
<br><br>
<div id="add_button_1">
<ion-button color="success" (click)="presentActionSheet('Image_1')">
<ion-icon name="camera"></ion-icon>
Add Image 1
</ion-button>
</div>
<div id="change_button_1" hidden>
<ion-button color="primary" (click)="presentActionSheet('Image_1')">
<ion-icon name="camera" hidden></ion-icon>
change
</ion-button>
</div>
</ion-item>
<ion-item>
<ion-thumbnail id="thumb_2" hidden>
<img src="{{img_2}}">
</ion-thumbnail>
<br><br>
<div id="add_button_2">
<ion-button color="success" (click)="presentActionSheet('Image_2')">
<ion-icon name="camera"></ion-icon>
Add Image 2
</ion-button>
</div>
<div id="change_button_2" hidden>
<ion-button color="primary" (click)="presentActionSheet('Image_2')">
<ion-icon name="camera" hidden></ion-icon>
Change
</ion-button>
</div>
</ion-item>
<ion-item>
<ion-thumbnail id="thumb_3" hidden>
<img src="{{img_3}}">
</ion-thumbnail>
<br><br>
<div id="add_button_3">
<ion-button color="success" (click)="presentActionSheet('Image_3')">
<ion-icon name="camera"></ion-icon>
Add Image 3
</ion-button>
</div>
<div id="change_button_3" hidden>
<ion-button color="primary" (click)="presentActionSheet('Image_3')">
<ion-icon name="camera" hidden></ion-icon>
change
</ion-button>
</div>
</ion-item>
<br><br>
<ion-button expand="block" color="tertiary" (click)="get_form_data()"> Submit your dress</ion-button>
</ion-card-content>
</ion-card>
</ion-content>
HTML很好用,当我发送数据时,我检查了network
标签,并且正在发送请求。
这是我得到{"item_image_1":["The submitted data was not a file. Check the encoding type on the form."],"item_image_2":["The submitted data was not a file. Check the encoding type on the form."],"item_image_3":["The submitted data was not a file. Check the encoding type on the form."]}
答案 0 :(得分:2)
您在这里遇到问题:
this.camera.getPicture(options).then((imageData) => {
const base64Image = 'data:image/jpeg;base64,' + imageData;
},
this.img_2 = base64Image;
在相机拍照之前已设置this.img_2
变量,这意味着this.img_2
将为空。
将其移到您的promise回调中:
this.camera.getPicture(options).then((imageData) => {
const base64Image = 'data:image/jpeg;base64,' + imageData;
this.img_2 = base64Image;
},
确保在使用图像之前先获得图像。