Angular 如何在同一请求中发布JSON数据和文件
我想在同一个请求中实现post文件和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
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',
});
}
FormDataappend()
的定义是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中检索。