Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 如何在同一请求中发布JSON数据和文件_Angular_Typescript_File Upload - Fatal编程技术网

Angular 如何在同一请求中发布JSON数据和文件

Angular 如何在同一请求中发布JSON数据和文件,angular,typescript,file-upload,Angular,Typescript,File Upload,我想在同一个请求中实现post文件和Json数据 以下是上传文件代码: upload(url:string,file:File):Observable<{complate:number,progress?:number,data?:Object}>{ return Observable.create(observer => { const formData:FormData = new FormData(), xhr:XMLHttpReq

我想在同一个请求中实现post文件和Json数据

以下是上传文件代码:

upload(url:string,file:File):Observable<{complate:number,progress?:number,data?:Object}>{


    return Observable.create(observer => {
      const formData:FormData = new FormData(),
        xhr:XMLHttpRequest = new XMLHttpRequest();
      formData.append('uploadfile', file);


      formData.append("_csrf", this.tokenService.getCsrf());
      xhr.open('POST',url, true);
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          if (xhr.status === 200) {
            observer.next({complate:1,progress:100,data:JSON.parse(xhr.response)});
            observer.complete();
          } else {
            observer.error(xhr.response);
          }
        }
      };

      xhr.upload.onprogress = (event) => {
        observer.next({complate:0,progress:Math.round(event.loaded / event.total * 100)});
      };


      const headers=new Headers();
      let token: string = localStorage.getItem('access-token');
      xhr.setRequestHeader('Authorization', `Bearer ${token}`);
      xhr.send(formData);
    }).share();
upload(url:string,file:file):可观察{
返回可观察的。创建(观察者=>{
const formData:formData=new formData(),
xhr:XMLHttpRequest=新的XMLHttpRequest();
append('uploadfile',file);
append(“_csrf”,this.tokenService.getCsrf());
xhr.open('POST',url,true);
xhr.onreadystatechange=()=>{
if(xhr.readyState==4){
如果(xhr.status==200){
next({complete:1,progress:100,data:JSON.parse(xhr.response)});
observer.complete();
}否则{
观察者错误(xhr响应);
}
}
};
xhr.upload.onprogress=(事件)=>{
下一步({suplate:0,progress:Math.round(event.loaded/event.total*100)});
};
常量头=新头();
let-token:string=localStorage.getItem('access-token');
setRequestHeader('Authorization','Bearer${token}`);
xhr.send(formData);
}).share();

如何集成angular2http.post(url,JSON.stringify(data))。

所以我也一直在尝试这样做,对于一些看起来非常简单的问题,我最终很难找到一个解决方案。希望一些同事帮助我,我们找到了一些合理的解决方案

这些文档对我们帮助很大:

这是角度代码:

class SomeService {
  someMethod(fileToUpload: File, name: string, version: string) {
    const formData: FormData = new FormData();
    formData.append('file', fileToUpload, fileToUpload.name);

    const overrides = {
      name,
      version,
    };

    const blobOverrides = new Blob([JSON.stringify(overrides)], {
      type: 'application/json',
    });

    formData.append('overrides', blobOverrides);

    const req = new HttpRequest('POST', `some-url`, formData);

    return this.http.request(req);
  }
}

如上所述,使用Blob是关键,下面是一个如何做到这一点的示例。

下面的客户端和服务代码在我的解决方案中运行良好,请检查这是否有帮助

客户端代码:

    AddModelData(modelData: ModelData, file: any): Observable<any> 
    {
      let urlPath = 'api/SampleActionMethod/AddModelData';
      const mData = JSON.stringify(modelData);
      const formData = new FormData();
      formData.append('data', mData);
      if (file) {
        formData.append('file', file, file.name);
      }
      return this._http.post(this.settings.apiEndPoint + urlPath, formData);
    }
public IActionResult PostMethod(IFormFile file)
{      
  try
  {                
    var modelData = JsonConvert.DeserializeObject<ModelData>(Request.Form["data"]); 
    //data is the key that is being passed from client side
    //file in params will have the posted file

    //Do Something with data and file......

    return Ok();
  }
  catch (Exception e)
  {
    return StatusCode(500, e.Message);
  }
}
AddModelData(modelData:modelData,file:any):可观察
{
设urlPath='api/SampleActionMethod/AddModelData';
const mData=JSON.stringify(modelData);
const formData=new formData();
formData.append('data',mData);
如果(文件){
formData.append('file',file,file.name);
}
返回此。_http.post(this.settings.apident+urlPath,formData);
}
服务端代码:

    AddModelData(modelData: ModelData, file: any): Observable<any> 
    {
      let urlPath = 'api/SampleActionMethod/AddModelData';
      const mData = JSON.stringify(modelData);
      const formData = new FormData();
      formData.append('data', mData);
      if (file) {
        formData.append('file', file, file.name);
      }
      return this._http.post(this.settings.apiEndPoint + urlPath, formData);
    }
public IActionResult PostMethod(IFormFile file)
{      
  try
  {                
    var modelData = JsonConvert.DeserializeObject<ModelData>(Request.Form["data"]); 
    //data is the key that is being passed from client side
    //file in params will have the posted file

    //Do Something with data and file......

    return Ok();
  }
  catch (Exception e)
  {
    return StatusCode(500, e.Message);
  }
}
public IActionResult PostMethod(ifformfile)
{      
尝试
{                
var modelData=JsonConvert.DeserializeObject(Request.Form[“data”]);
//数据是从客户端传递的密钥
//params中的文件将具有已发布的文件
//对数据和文件做些什么。。。。。。
返回Ok();
}
捕获(例外e)
{
返回状态代码(500,例如消息);
}
}

我的经理@Jesse想出的方法是:

public uploadFiles(id: ServerID, brd: File, sch: File, args: any[]): Observable<Blob> {
        const data = new FormData();
        data.append('brd', brd);
        data.append('sch', sch);
        data.append('data', JSON.stringify(args));
        return this.httpClient.post(URL, data, {
            responseType: 'blob',
        });
    }
公共上传文件(id:ServerID,brd:File,sch:File,args:any[]):可见{
const data=新表单数据();
附加数据('brd',brd);
数据。附加(“sch”,sch);
data.append('data',JSON.stringify(args));
返回此.httpClient.post(URL、数据、{
responseType:'blob',
});
}
FormData
append()
的定义是
append(名称:string,值:string | Blob,fileName?:string):void;
,它允许您向其追加JSON参数或上载文件。

//app.component.html
//app.component.html

<input type="file" name="file" (change)="onChange($event)">
<button (click)="onSubmisson()" [disabled]="file==null" >Submit</button>

//app.component.ts

file:File = null;

onChange(event){
 this.file = event.target.files[0]
}

onSubmisson(){
 this._auth.uploadFileAndData(this.file).subscribe(
 res => {
    console.log(res);
 },err => {
    console.log(err);
 });
}

//upload.service.ts

uploadFileAndData(file){
  var test = {test:"test"}
  const formData = new FormData();
  formData.append('data', JSON.stringify(test));
  formData.append('file', file, file.name);
  return this._http.post<any>(this._uploadurl, formData);
}

//node server

var multer = require('multer');
var path = require('path');

var storage = multer.diskStorage({
  // destination
  destination: function (req, file, cb) {
    cb(null, './uploads/')
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname);
  }
});

var upload = multer({ storage: storage }).array("file", 12);

router.post("/upload",  function(req , res){
    upload(req, res, function (err) {
        if(err){
            console.log(err);
        }else{
            console.log(req.body);
            console.log('files', req.files);
        }
    })
    res.status(200).send({});
});

// output

{ data: '{"test":"test"}' }

files [ { fieldname: 'file',
    originalname: 'acfcdea5-28d2-4f2e-a897-1aef3507193d.jpg',
    encoding: '7bit',
    mimetype: 'image/jpeg',
    destination: './uploads/',
    filename: 'acfcdea5-28d2-4f2e-a897-1aef3507193d.jpg',
    path: 'uploads\\acfcdea5-28d2-4f2e-a897-1aef3507193d.jpg',
    size: 49647 } ]
提交 //app.component.ts file:file=null; onChange(事件){ this.file=event.target.files[0] } onSubmisson(){ 此.u auth.uploadFileAndData(this.file).subscribe( res=>{ 控制台日志(res); },err=>{ 控制台日志(err); }); } //upload.service.ts 上传文件和数据(文件){ var test={test:“test”} const formData=new formData(); append('data',JSON.stringify(test)); formData.append('file',file,file.name); 返回此.uHTTP.post(此.uUploadURL,formData); } //节点服务器 var multer=需要('multer'); var path=require('path'); var storage=multer.diskStorage({ //目的地 目标:功能(请求、文件、cb){ cb(空“./上传/”) }, 文件名:函数(请求、文件、cb){ cb(null,file.originalname); } }); var upload=multer({storage:storage}).array(“file”,12); 路由器。post(“/upload”),功能(请求、恢复){ 上传(请求、恢复、功能(错误){ 如果(错误){ 控制台日志(err); }否则{ 控制台日志(请求主体); console.log('files',req.files); } }) res.status(200).send({}); }); //输出 {数据:{“测试”:“测试”} 文件[{fieldname:'文件', 原始名称:“acfcdea5-28d2-4f2e-a897-1aef3507193d.jpg”, 编码:“7bit”, mimetype:'image/jpeg', 目的地:'./上传/', 文件名:“acfcdea5-28d2-4f2e-a897-1aef3507193d.jpg”, 路径:“上传\\acfcdea5-28d2-4f2e-a897-1aef3507193d.jpg”, 大小:49647}]
angular2目前不支持http.post中的文件:但您仍然可以使用
arraybuffer
Blob
发送您的文件。此外,要实现渐进,请检查以下答案:使用
Blob
?是否有示例?我没有示例,但它需要非常复杂的操作(从表单中获取文件,从文件中创建blob,将blob添加到表单中,等等)。我认为您的解决方案是目前最好的解决方案。(仅使用基本xhr请求)。我也面临着同样的问题。我需要提交包含文本和文件数据的表单。有没有办法在Angualr JS 2中实现?嗨@Maxime,你应该如何在后端解析JSON数据?很抱歉,Brian,但我不再负责这个问题,甚至不再在这家公司工作。祝你好运,谢谢@Maxime的支持倾向于回答:)很好的解决方案。我注意到,我们不需要API级别的IFormFile负载,这些值可以从HttpRequest中检索。