【发布时间】:2018-02-01 08:41:27
【问题描述】:
我正在尝试在节点 js 中使用 multer 上传 angular 5 的图像。但它不做上传。
我正在使用 formData 获取角度 5 中的文件详细信息并将数据发送到后端。但是这里没有上传。
这是我现在拥有的代码
event-create.component.html 看起来像这样
<div class="container col-md-10">
<h1 class="page-header">Create Event</h1>
<form [formGroup] = "form" (ngSubmit)="onEventSubmit()">
<fieldset>
<div class="form-group">
<label for="eventname">Event Name</label>
<div class='input-group date col-sm-6'>
<input type="text" class="form-control" autocomplete="off" placeholder="Event Name" formControlName="eventname">
</div>
</div>
<div class="form-group">
<label for="eventimage">Event Image</label>
<div class="input-group">
<span class="input-group-btn">
<span class="btn btn-default btn-file">
Browse… <input type="file" id="eventimage" name="eventimage" formControlName="eventimage" (change)="fileChangeEvent($event)" >
</span>
</span>
<input type="text" class="form-control" readonly>
</div>
<img id='img-upload'/>
</div>
<input type="submit" class="btn btn-primary" value="Submit">
</fieldset>
</form>
</div>
event-create.component.ts 是这样的
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { FormControlName } from '@angular/forms/src/directives/reactive_directives/form_control_name';
import { EventService } from '../event.service';
import { Response } from '@angular/http';
@Component({
selector: 'app-event-create',
templateUrl: './event-create.component.html',
styleUrls: ['./event-create.component.css']
})
export class EventCreateComponent implements OnInit {
private file_form;
form : FormGroup;
message;
messageClass;
processing = false;
filesToUpload: Array<File> = [];
constructor(
private formBuilder : FormBuilder,
private eventService : EventService,
) { this.createEventForm(); }
createEventForm() {
this.form = this.formBuilder.group({
eventname: ['', Validators.required],
eventimage: [''],
})
}
ngOnInit() {
}
onEventSubmit() {
const event = {
eventname : this.form.value.eventname,
eventimage : this.file_form,
}
this.eventService.addNewEvent(event).subscribe( data => {
if( !data.success ) {
this.messageClass = 'alert alert-danger';
}
else {
this.messageClass = 'alert alert-success';
}
});
}
fileChangeEvent(event) {
let files = event.target.files;
if(files.length > 0) {
let file = files[0];
let formData = new FormData();
formData.append('eventimage', file, file.name);
this.file_form = formData;
}
}
}
event.service.ts 看起来像这样
import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs';
import { HttpClientModule } from '@angular/common/http';
import { HttpClient } from "@angular/common/http";
import 'rxjs/add/operator/map';
@Injectable()
export class EventService {
domain = 'http://localhost:8080';
headers = new Headers({ 'Content-Type': 'application/json' });
constructor(
private http: Http,
) { }
addNewEvent(event) {
return this.http.post(this.domain + '/event', {headers: this.headers}, event).map(res => res.json());
}
}
我的 express.js 看起来像这样
/* ===================
Import Node Modules
=================== */
const express = require('express');
const app = express();
const router = express.Router();
const mongoose = require('mongoose');
const config = require('./database');
const path = require('path');
const appRoot = require('app-root-path') ;
const event = require('./routes/event.router');
const bodyParser = require('body-parser');
const multer = require('multer');
const cors = require('cors');
const port = process.env.PORT || 8080; // Allows heroku to set port
mongoose.Promise = global.Promise;
process.env.NODE_ENV = 'production';
// Database Connection
mongoose.connect(config.uri, {
useMongoClient: true,
}, (err) => {
// Check if database was able to connect
if (err) {
console.log('Could NOT connect to database: ', err); // Return error message
} else {
console.log('Connected to ' + config.db); // Return success message
}
});
app.use(cors());
//app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(appRoot.path, 'dist')));
app.use('/event', event);
// Serve only the static files form the dist directory
app.get('*', (req, res) => {
res.sendFile(path.join(appRoot.path, 'dist/index.html'));
});
// Start Server: Listen on port 8080
app.listen(port, () => {
console.log('Listening on port ' + port + ' in ' + process.env.NODE_ENV + ' mode');
});
event.router.js 长这样
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
const Event = require('../../model/event.model');
const multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
});
var upload = multer({ storage: storage }).single('eventimage');
/* SAVE EVENT */
//app.post('/api/image', upload.array('image', 5), (req, res, next) => {
router.post('/', function(req, res, next) {
upload(req, res, function(err) {
console.log(req.file); //showing undefined
console.log(req.files); //showing undefined
if (err) {
// An error occurred when uploading
throw err;
}
res.json({
sucess: true,
message: 'Image was uploaded successfully'
});
// Everything went fine
});
});
所以有人可以告诉我我在这里做错了什么。任何帮助和建议都会非常重要。
这是来自 chrome 开发工具的屏幕截图。
我不知道为什么 eventimage 显示为空白对象。
【问题讨论】:
-
这是一个很好的解释,关于使用 formData 以 Angular 5 上传文件:stackoverflow.com/questions/47936183/angular-5-file-upload/…,这是另一个示例:stackoverflow.com/questions/45690051/…
-
@GregorDoroschenko 我已经尝试过这种方法,但仍然无法正常工作。
标签: javascript node.js angular express multer