【问题标题】:angular 5 image upload with multer does not uploading files使用 multer 上传 angular 5 图像不上传文件
【发布时间】: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 显示为空白对象。

【问题讨论】:

标签: javascript node.js angular express multer


【解决方案1】:
addNewEvent(event) {
    return this.http.post(this.domain + '/event', {headers: this.headers}, event).map(res => res.json());
  }

如果我没记错的话,您似乎只是在发送标头 - 认为您的参数顺序错误。来自文档:

  post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>

因此您的标题选项位于正文之前。试试这个:

return this.http.post(this.domain + '/event',  event, {headers: this.headers}).map(res => res.json());

【讨论】:

  • 我尝试了你所说的,但它在终端中显示错误,如 Error: Can't set headers after they are sent. 如果我试图在没有标题的情况下发送它,那么它会显示错误,如我在 console.log(req.file); 所做的未定义的地方
  • 你能调试一下具体发布的内容吗?就像您所有的请求标头等一样,这可能有助于确定您的代码何时发送。看到这个答案:stackoverflow.com/questions/15603561/…
  • 我已经用屏幕截图更新了我的问题。请检查一下。
猜你喜欢
  • 2020-12-31
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-25
  • 2021-02-04
  • 2019-12-05
  • 2019-07-31
相关资源
最近更新 更多