所有文章

Ionic V4 用 HttpClient 上傳圖片

原本一直是用 cordova-plugin-file-transfer 來實作圖片上傳的部分,除了帶額外的 params 都失敗之外,沒什麼大問題,但因為這外掛已經不推薦使用了,所以還是趁這次開發新專案時換到 HttpClient 上。

上傳圖片,這真的不是件什麼很困難的事情,但弄來弄去就是弄不好,後端接到的 post 都是空的,於是只好請教 Google 大神,找到這篇文章。
原來是 content-type 的問題,只要確保你的 Request 再送出去的時候沒有任何 content-type 讓 HttpClient 自己去處理這樣就可以了。

看一下 page.ts 的部份,通常我們都會使用 intercept 來設定一些 headers 的預設值,像是 token 或是 content-type,如果你也有這樣做,可以用加上標記的部分來讓 intercept 不要動作,例如上面的 ContentTypeSkip。

javascript
openCamera() {
    const options: CameraOptions = {
        quality: 50,
        destinationType: this.camera.DestinationType.FILE_URI,
        encodingType: this.camera.EncodingType.JPEG,
        mediaType: this.camera.MediaType.PICTURE
    };
    this.camera.getPicture(options).then((fileUri) => {
        this.uploadPhoto(fileUri);
    }).catch(cameraError => {
        console.log(cameraError);
    });
}

private readFile(file: any) {
    const reader = new FileReader();
    reader.onloadend = () => {
        const formData = new FormData();
        const imgBlob = new Blob([reader.result], {type: file.type});
        formData.append('type', 'avatar');
        formData.append('file', imgBlob, file.name);
        this.postData(formData);
    };
    reader.readAsArrayBuffer(file);
}


private postData(formData) {
    const httpOptions = {
        headers: new HttpHeaders({
            ContentTypeSkip:  'Content-Type-Skip',
        })
    };

    this.http.post(environment.API_URL + 'members/avatar', formData, httpOptions)
    .subscribe(response => {
        console.log(response);
    }, avatarError => {
        console.log(avatarError);
    });
}

intercept 再加上判斷式

javascript
if (!request.headers.has('ContentTypeSkip')) {
    if (!request.headers.has('Content-Type')) {
        request = request.clone({headers: request.headers.set('Content-Type', 'application/json')});
    }
}

以上就是這次踩的坑,只要注意到這一點,其他就沒什麼大問題了。