使用后期请求从ionic 4发送图像

时间:2019-03-28 11:46:38

标签: angular base64 ionic4

我正在尝试使用发布请求发送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."]}

的回复

1 个答案:

答案 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;
            }, 

确保在使用图像之前先获得图像。