如何使用 http.post 上传文件和表单数据

Posted

技术标签:

【中文标题】如何使用 http.post 上传文件和表单数据【英文标题】:How to upload a file along with form data using http.post 【发布时间】:2018-03-08 10:54:20 【问题描述】:

我正在使用http.post 提交包含titledescription 等字段的表单,它工作正常。我还允许用户使用相机拍摄照片并将其保存为base64 格式的字符串。我需要通过同一个 POST 请求将这张照片提交给服务器。我怎样才能做到这一点?到目前为止,我的代码如下,服务器在名为“photo”的字段中查找上传的照片:

headers = new Headers('Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8');
options = new RequestOptions( headers: this.headers );

let data = 
  title: item.title,
  description: item.description
;

let params = new URLSearchParams();
for(let key in data)
    params.set(key, data[key]) 


this.http.post('http://example.com/items', params.toString(), this.options).subscribe(
  (result) => 
    console.log("success!");
  ,
  (err) => 
    console.log(JSON.stringify(err));
  
);

【问题讨论】:

【参考方案1】:

您必须使用文件传输插件来上传文件。我建议使用文件而不是 base64。 Base64 是一个非常大的字符串,当图像被高分辨率捕获时。

html

<button (click)="takePicture()">Take a picture</button>

ts

takePicture()

    const options: CameraOptions = 
        quality: 100,
        destinationType: this.camera.DestinationType.FILE_URI,
        encodingType: this.camera.EncodingType.JPEG,
        mediaType: this.camera.MediaType.PICTURE
    
    this.camera.getPicture(options).then((imageData) => 
        this.allImageData = imageData;
        var data = 
            "imgUrl": this.allImageData,
            "challenge_id": this.challenges_id
        
        let uploadImageModal = this.modalCtrl.create(UploadBodyImagePage, data: data );
        uploadImageModal.present();
        uploadImageModal.onDidDismiss(data => 
            this.viewCtrl.dismiss();
        );
    , (err) => 
    
        // alert("error");
    

    );

您可以使用以下函数向服务器发送数据

uploadData()

    this.disabledButton = true;
    this.commonProvider.retrieve('userData').then(res=> 

        const fileTransfer: TransferObject = this.transfer.create();
        var options = 
            fileKey: "file",
            fileName: "filename",
            chunkedMode: false,
            mimeType: "multipart/form-data",
            params : 
                "methodName": "saveBodyUpdate",
                "challenge_id": this.challenge_id,
                "userId": res['user_id'],
                "loginToken": res['loginToken'],
                "days_id":"1",
                "weight": this.myweight
            
        ;  
        fileTransfer.onProgress((e)=>
        
            this.prg=(e.lengthComputable) ?  Math.round((e.loaded * 100) / e.total) : -1; 
            this.changeDetectorRef.detectChanges();
        );
        fileTransfer.upload(this.imgSrcData, this.apiUrl, options).then((res) => 
           
            console.log(JSON.stringify(res));
            this.viewCtrl.dismiss();
        ,(err)=> 
            this.viewCtrl.dismiss();
        );
    )  

【讨论】:

我想使用 POST 请求提交照片。 你只需要通过base64发帖吗? 不,camera.DestinationType 中定义的任何类型都可以接受(DATA_URL、FILE_URI、NATIVE_URI)。 您只是通过相机捕获图像。你的http.post 方法在哪里?我认为您忘记透露位于UploadBodyImagePage 页面中的代码。 谢谢,但它只绑定到一个文件。如果我想通过同一个调用上传两个或更多文件怎么办?【参考方案2】:

这可能会有所帮助:(我在后端使用了 nodejs 和 mongodb)

HTML::

<input type=“file” name=“image” accept=“image/*” (change)=“changeListener($event)”>

.ts

file: File;
changeListener($event): void 
this.file = $event.target.files[0];
this.imagesProvider.test1(this.file) // Calls test1() function in imagesProvider.ts

imagesProvider.ts:

test1(data)
 var options = ;
let body = new FormData();
body.append(‘image’, data);
body.append(‘desc’, “testing”);
this.http.post(“Your api endpoint”, body, options).subscribe(res => 
console.log(res);
);

【讨论】:

以上是关于如何使用 http.post 上传文件和表单数据的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 中上传带有 http.post 和注册表单的图像?

JAVA模拟HTTP post请求上传文件

HTTP POST请求报文格式分析与Java实现文件上传

IONIC HTTP post multipart/form-data - 图像与 JSON 一起上传

如何使用HTTP POST multipart / form-data将文件上传到服务器?

如何使用 HTTP POST 使用 HTML 和 PHP 选择和上传多个文件?