可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to implement post file and Json data in the same request .
below is the upload file code :
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();
How to integration with angular2 http.post(url, JSON.stringify(data)).
回答1:
So I've been trying to do that too, and for something which look really simple I ended up with a lot of trouble to figure out a solution. Hopefully some coworkers helped me and we came up with something reasonable.
This documentation helped us a lot: https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
And here's the Angular code:
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);
}
}
As @Supamiu said, using Blob was the key, and here's an example how to do that.
回答2:
//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 } ]
回答3:
The below client and service code works fine in my solution, check if this helps
Client Side Code:
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);
}
Service Side Code:
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);
}
}
回答4:
The way my manager @Jesse come up with is like:
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',
});
}
The definition of the FormData append()
is append(name: string, value: string | Blob, fileName?: string): void;
which allows you to append JSON parameters to it or upload a file.