我正在使用带有Node js,express和mongodb的angular 5来上传带有一些数据的图像。所有数据都保存到mongodb没有任何问题但是当我试图显示上传的图像时,它显示404未找到,即使图像仍然存在于uploads文件夹中。我甚至尝试使用图像名称对路径进行硬编码,但仍显示404错误。但是如果我在角度代码中做出一些改变(在一些chnages之后构建角度)或者构建角度它会显示图像。
我在stackoverflow上搜索并得到类似this的问题,所以现在我在nodejs根文件夹中上传图像。
这是express.js的代码
/* ===================
Import Node Modules
=================== */
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const passport = require('passport');
const bodyParser = require('body-parser');
const path = require('path');
const appRoot = require('app-root-path');
const mongoose = require('mongoose');
const app = express();
const router = express.Router();
const multer = require('multer');
//custom module
const event = require('../config/routes/event.router');
const port = process.env.PORT || 8080; // Allows heroku to set port
mongoose.Promise = global.Promise;
//assigning value
process.env.NODE_ENV = 'devlopment';
/**
* Assiging port to server
*/
const server = app.listen(port, () => {
console.log('Listening on port ' + port + ' in ' + process.env.NODE_ENV + ' mode');
});
/**
* 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
}
});
/**
* Require Middleware
*/
app.use(helmet());
app.use(passport.initialize());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
/**
* Every Http request start from index file
*/
app.use(express.static(path.join(appRoot.path, 'dist')));
app.use('/api/event', event); //Event Router
app.get('*', (req, res) => {
res.sendFile(path.join(appRoot.path, 'dist/index.html'));
});
这是我的event.router.js文件看起来像这样
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
const Event = require('../../model/event.model');
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads/');
},
filename: function (req, file, cb) {
let ext = file.originalname.substring(file.originalname.lastIndexOf('.'), file.originalname.length);
cb(null, Date.now() + ext);
}
})
var upload = multer({ storage: storage }).single('eventimage');
/* SAVE EVENT */
router.post('/', function(req, res, next) {
upload(req, res, function(err) {
if( req.body.eventname == undefined || req.body.eventname == '' ) {
res.json({ success : false, message: 'You must provide event name!' });
}
else if( req.file == undefined || req.file == '' ) {
res.json({ success : false, message: 'You must provide event image!' });
}
else {
let event = new Event ({
_id : new mongoose.Types.ObjectId(),
eventname : req.body.eventname,
eventimage : req.file,
});
event.save((err) => {
if(err) {
if( err.errors ) {
if( err.errors.eventname ) {
res.json({ success: false, message: err.errors.eventname.message });
}
}
else {
res.json({ success: false, message: 'Could not save Event. Error: ', err });
}
}
else {
res.json({ success: true, message: 'Event saved'});
}
});
}
});
});
module.exports = router;
这是我的event-create.component.html看起来像
<div class="container col-md-12">
<h1 class="page-header">Create Event</h1>
<form [formGroup] = "form" (ngSubmit)="onEventSubmit()">
<fieldset>
<div class="form-group">
<label for="eventname">Event Name</label>
<input type="text" class="form-control" autocomplete="off" placeholder="Event Name" formControlName="eventname">
</div>
<div class="form-group">
<label for="eventimage">Upload Image For Event</label>
<image-upload name="eventimage" [max]="1" [buttonCaption]="'Select Event Image!'"
[extensions]="['jpg','png']" (removed)="onRemoved($event)"
(uploadFinished)="onUploadFinished($event)"
(uploadStateChanged)="onUploadStateChanged($event)" [class]="'eventimage'">
</image-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 { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { FormControlName } from '@angular/forms/src/directives/reactive_directives/form_control_name';
import { FileHolder } from "angular2-image-upload/lib/image-upload/image-upload.component";
import { EventService } from '../event.service';
@Component({
selector: 'app-event-create',
templateUrl: './event-create.component.html',
styleUrls: ['./event-create.component.css']
})
export class EventCreateComponent implements OnInit {
public file_form;
public eventData;
form : FormGroup;
formData = new FormData();
constructor(
private formBuilder : FormBuilder,
private eventService : EventService
) { this.createEventForm() }
createEventForm() {
this.form = this.formBuilder.group({
eventname: ['', Validators.compose([
Validators.required,
Validators.minLength(5)
])],
eventimage: ['',]
})
}
ngOnInit() {
this.form = new FormGroup({
eventname: new FormControl('', [ Validators.required, Validators.minLength(5)]),
eventimage: new FormControl(''),
});
}
onEventSubmit() {
if( this.file_form == undefined ) {
let formData:FormData = new FormData();
this.file_form = formData;
}
this.eventData = this.file_form;
this.eventData.append('eventname', this.form.value.eventname);
this.eventService.addNewEvent(this.eventData).subscribe( data => {
if( !data.success ) {
this.messageClass = 'alert alert-danger';
this.message = data.message;
}
else {
this.messageClass = 'alert alert-success';
this.message = data.message;
}
});
}
public onUploadFinished(file: FileHolder) {
this.formData.append('eventimage', file.file, file.file.name);
this.file_form = this.formData;
}
}
这是事件详细信息,我从mongodb获取数据与图像
event-detail.component.ts看起来像这样
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params} from "@angular/router";
import { HttpClient } from '@angular/common/http';
import { EventService } from '../../../admin/events/event.service';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
@Component({
selector: 'app-event-detail',
templateUrl: './event-detail.component.html',
styleUrls: ['./event-detail.component.css'],
})
export class EventDetailComponent implements OnInit {
event = {};
eventname;
absolutePath = 'public/uploads';
constructor(
private route: ActivatedRoute,
protected eventService: EventService,
) { }
ngOnInit() {
this.route.params.switchMap((params: Params) => {
let id = params['id'];
return this.eventService.getEvent(id);
}).subscribe(response => {
this.event = response;
this.eventname = this.event['eventname'];
this.eventImage = this.event['eventimage']['filename'];
}, err => {
console.log(err);
});
}
}
和event-details.component.html看起来像这样
<div class="main-content">
<div class="container">
<div class="row">
<div class="col-md-5">
<img class="event_listing" src= "{absolutePath}/{eventImage}">
</div>
<div class="col-md-7">
<h4 class="page-header">{{eventname}}</h4>
</div>
</div>
</div>
</div>
出现此问题是因为我们使用dist文件夹作为静态文件夹。
app.use(express.static(path.join(appRoot.path, 'dist')));
我所做的是,我使用你正在做的过程构建整个应用程序,一旦我们在服务器上托管网站,就不需要再次重新构建。只需确保您的上传功能正常运行。