基于Ionic+Angular+Cordova的音频文件上传至服务器问题排查
问题描述
我正在尝试使用Ionic、Angular和Cordova,将通过MediaObject创建的音频文件上传至服务器,使用了Native File插件和@angular/common/http中的HttpClient。
服务器端无法通过PHP $_FILES['audio']获取到文件,我无法排查出问题所在,或许需要使用file.getFile()来获取文件,但尝试后并未成功。
我已经尝试将Content-Type设置为"multipart/form-data"、"file"、"false"、"undefined",但服务器端仍无法获取文件。
以下是我的代码,已引入所有必要依赖,控制台无报错:
audio: MediaObject; audioFile: FileEntry; fileName: string; startAudio() { this.fileName = "audio" + Date.now() + ".mp3"; this.audio = this.media.create(this.fileName); this.audio.startRecord(); } async finishAudio(){ this.audio.stopRecord(); const formAudio = new FormData(); //this.audioFile = this.file.getFile(this.file.externalDataDirectory.replace(/file:\/\//g, ''), this.fileName, { create: false }); const buffer = await this.file.readAsArrayBuffer(this.file.externalDataDirectory, this.fileName); const fileBlob = new Blob([buffer], {type:'audio/mp3'}); console.log(buffer); formAudio.append("audio", fileBlob, this.fileName); this.responseAudioForm = this.audioFormService.postFile(formArchivo); this.responseAudioForm.subscribe(data =>{ this.responseDataAudioForm = data ; let title = data.title; let message = data.message; }); } /* AudioFormService */ postFile(formData:FormData): Observable<any>{ //console.log(fields); const httpOptions = { headers: new HttpHeaders({ "Content-Type": "application/x-www-form-urlencoded", }) } this.presentLoading(); return this.httpClient.post(this.apiUpdateURL, formData, httpOptions) .pipe( map(results => { console.log("RAW:",results); this.dismissLoading(); this.showToast(); return results; }), catchError(err => { console.log("Handling error:", err); this.showAlert(err.statusText,err.name,err.message); return throwError(err); }), catchError(err => { console.log("caught rethrown:", err); return of([]); }), ); }
解决方案(供有需要的开发者参考)
audio: MediaObject; audioFile: FileEntry; responseAyudaForm: Observable<any>; responseDataAyudaForm: any = []; // Start audio recording async startAudio() { var path: string = ""; if(this.platform.is("ios")){ path = this.file.tempDirectory; this.fileName = new Date().getTime() + ".mp3"; this.audioFile = await this.file.createFile(path, this.fileName, true); this.audio = this.media.create(this.file.tempDirectory.replace(/^file:\/\//, '') + this.fileName); } else { path = this.file.externalDataDirectory; this.fileName = new Date().getTime() + ".mp3"; this.audioFile = await this.file.createFile(path, this.fileName, true); this.audio = this.media.create(this.audioFile.nativeURL); } this.audio.startRecord(); console.log("Record Start"); } // Stop audio recording and upload file to server async finishAudio() { this.audio.stopRecord(); console.log("Stop Recording"); // Upload the new recording await new Promise(resolve => setTimeout(resolve, 200)); console.log("Start Blob convertion"); const blob = await this.getBlobFromFileEntry(this.audioFile); console.log("Finish Blob convertion"); const formFile = new FormData(); formFile.append("audio", blob, this.fileName); this.responseAyudaForm = this.ayudaService.postFile(formFile); this.responseAyudaForm.subscribe(data =>{ this.responseDataAyudaForm = data ; let title = data.title; let message = data.message; }); } getBlobFromFileEntry(fileEntry: FileEntry): Promise<Blob> { return new Promise((resolve, reject) => { fileEntry.file((file) => { const reader = new FileReader(); reader.onloadend = function(e) { try { const { result: buffer } = e.target const blob = new Blob( [new Uint8Array(buffer as any)], { type: 'audio/mp3' } /* or file.type */ ); console.log(blob); resolve(blob); } catch (error) { reject(error); } }; reader.onabort = (ev) => reject(ev); reader.onerror = (ev) => reject(ev); reader.readAsArrayBuffer(file); }, reject) }); } /** / AyudaService.postFile() **/ postFile(formData:FormData): Observable<any>{ /*const httpOptions = { headers: new HttpHeaders({ "Content-Type": 'file', }) }*/ this.presentLoading(); return this.httpClient.post(this.apiAudioURL, formData) /* I removed the httpOptions parameter and it worked */ .pipe( map(results => { console.log("RAW:",results); this.dismissLoading(); this.showToast(); return results; }), catchError(err => { console.log("Handling error:", err); this.showAlert(err.statusText,err.name,err.message); return throwError(err); }), catchError(err => { console.log("Caught Rethrown:", err); return of([]); }), ); }
内容的提问来源于stack exchange,提问作者Nacho Cano
相关产品推荐
相关产品推荐

