Files not uploading with ng2-file-upload

2019-07-14 19:34发布

问题:

I'm trying to implement this library to upload images to a folder server:

When I click on "upload" button the server returns inmediately to the listener this.uploader.onCompleteItem on my fileUpload.ts component:

ImageUpload:uploaded: FileItem {url: "http://127.0.0.1:5000/api/uploadPhoto", headers: Array(0), withCredentials: false, formData: Array(0), isReady: false…}alias: "file"file: FileLikeObjectformData: Array(0)headers: Array(0)index: undefinedisCancel: falseisError: falseisReady: falseisSuccess: trueisUploaded: trueisUploading: falsemethod: "POST"options: ObjectautoUpload: falsedisableMultipart: falsefilters: Array(1)isHTML5: trueitemAlias: "file"removeAfterUpload: falseurl: "http://127.0.0.1:5000/api/uploadPhoto"__proto__: Objectprogress: 100some: Fileuploader: FileUploaderurl: "http://127.0.0.1:5000/api/uploadPhoto"withCredentials: false_file: File_xhr: XMLHttpRequest__proto__: Object 200 "uploaded"

But the file is not present on server. What would be doing wrong?

This is my backend: Server.js

     var express     = require("express"),
            app             = express(),
            cors            = require('cors'),
            bodyParser      = require("body-parser"),
            methodOverride  = require("method-override"),
            http            = require("http"),
            multer          = require('multer');
            server          = http.createServer(app),
            router          = express.Router()
                .....
                app.use(function (req, res, next) {
                res.header("Access-Control-Allow-Methods", "POST, PUT, OPTIONS, DELETE, GET");
                res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
                res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                res.header("Access-Control-Allow-Credentials", true);
                next();
            });
          //NEW
          app.use(bodyParser.urlencoded({extended: false}));
          app.use(bodyParser.json());
          app.use(cors());
          app.use(methodOverride());
          app.use(passport.initialize());
          app.use(busboyBodyParser());
          //
          app.use('/api', router);


                var upload = multer({dest: "./uploads/"}).single('file');


                router.post("/uploadPhoto",function (req, res) {
                        upload(req, res, function (err) {
                            if (err) {
                                console.log(err.toString())
                                return res.status(422).json("an Error occured")
                            }
                            console.log("done")
                            return res.status(200).json("uploaded")
                        })
                    }

                    );

This is my Frontend

fileUpload.ts

import { FileUploader } from 'ng2-file-upload';
...

public uploader:FileUploader;
constructor() {

        this.uploader  = new FileUploader({url: this.URL + "uploadPhoto", itemAlias: 'file'});

        this.uploader.onBeforeUploadItem = (item) => {
            item.withCredentials = false;
        }

        this.uploader.onCompleteItem = (item:any, response:any, status:any, headers:any) => {
            console.log("ImageUpload:uploaded:", item, status, response);
        };

    }

fileUpload.html

....
  <input name="file" type="file" ng2FileSelect [uploader]="uploader"/>

<button type="button" class="btn btn-success btn-xs"
                                    (click)="item.upload()" [disabled]="item.isReady || item.isUploading || item.isSuccess">
                                <span class="glyphicon glyphicon-upload"></span> upload
                            </button>
.....

Systemjs.config.js

(function (global) {
  System.config({
    paths: {
      // paths serve as alias
      'npm:': 'node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      app: 'app',

      // angular bundles//
      '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
      '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
      '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
      '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
      '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
      '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
      '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',


      // other libraries
      'rxjs':                       'npm:rxjs',
      '@angular/material': 'npm:@angular/material/bundles/material.umd.js',
      'hammerjs': 'npm:hammerjs/hammer.js',
      'ngx-sharebuttons': 'node_modules/ngx-sharebuttons/bundles/ngx-sharebuttons.umd.js',
      'ngx-cookie': 'npm:ngx-cookie/bundles/ngx-cookie.umd.js',
       'ng2-file-upload': 'npm:ng2-file-upload',
      '@agm/core': 'node_modules/@agm/core/core.umd.js',
       '@angular/animations': 'node_modules/@angular/animations/bundles/animations.umd.min.js',
       '@angular/animations/browser':'node_modules/@angular/animations/bundles/animations-browser.umd.js',
       '@angular/platform-browser/animations': 'node_modules/@angular/platform-browser/bundles/platform-browser-animations.umd.js'
//

    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      app: {
        main: './main.js',
        defaultExtension: 'js'
      },
        rxjs: {
            defaultExtension: 'js',
            main: 'Rx.js'
        },
        'ng2-file-upload': {
            main: 'ng2-file-upload.js',
            defaultExtension: 'js'
        }
    }
  });
})(this);

app.module

import { FileSelectDirective, FileDropDirective } from 'ng2-file-upload';
....
declarations:[FileSelectDirective,.....

package.json of my frontend

{
  "name": "angular2-quickstart",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
    "lite": "lite-server",
    "postinstall": "typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings"
  },
  "license": "ISC",
  "dependencies": {
    "@agm/core": "^1.0.0-beta.0",
    "@angular/animations": "^4.1.2",
    "@angular/common": "4.1.3",
    "@angular/compiler": "4.1.3",
    "@angular/compiler-cli": "4.1.3",
    "@angular/core": "4.1.3",
    "@angular/forms": "4.1.3",
    "@angular/http": "4.1.3",
    "@angular/material": "2.0.0-beta.5",
    "@angular/platform-browser": "4.1.3",
    "@angular/platform-browser-dynamic": "4.1.3",
    "@angular/router": "4.1.3",
    "@angular/upgrade": "4.1.3",
    "body-parser": "^1.15.2",
    "bootstrap": "^3.3.6",
    "core-js": "^2.4.1",
    "express": "^4.14.0",
    "hammerjs": "^2.0.8",
    "method-override": "^2.3.6",
    "ng2-file-upload": "^1.2.0",
    "ngx-cookie": "^1.0.0",
    "ngx-sharebuttons": "^3.0.0",
    "node-sass": "^4.5.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.4.0",
    "systemjs": "0.20.12",
    "zone.js": "^0.8.5"
  },
  "devDependencies": {
    "@types/hammerjs": "^2.0.34",
    "concurrently": "^3.2.0",
    "lite-server": "^2.2.2",
    "typescript": "^2.1.6",
    "typings": "^2.1.0"
  }
}

package.json backend

{
  "name": "Backend",
  "version": "0.0.0",
  "description": "Generated with Eclipse npm Tools",
  "main": "index.js",
  "author": "",
  "license": "ISC",
  "dependencies": {
    "agenda": "^0.9.1",
    "async": "^2.3.0",
    "bluebird": "^3.4.7",
    "body-parser": "^1.16.1",
    "busboy-body-parser": "^0.3.0",
    "crypto": "0.0.3",
    "email-verification": "^0.4.6",
    "express": "^4.14.1",
    "gridfs-stream": "^1.1.1",
    "method-override": "^2.3.7",
    "mongoose": "^4.8.5",
    "multer": "^1.3.0",
    "mysql": "^2.11.1",
    "nconf": "^0.8.4",
    "oauth2orize": "^1.7.0",
    "passport": "^0.3.2",
    "passport-http": "^0.3.0",
    "passport-http-bearer": "^1.0.1",
    "passport-oauth2-client-password": "^0.1.2"
  }
}

EDIT2:

I've half solved the problem with this:

    var express     = require("express"),
                app             = express(),
                cors            = require('cors'),
                bodyParser      = require("body-parser"),
                methodOverride  = require("method-override"),
                http            = require("http"),
                multer          = require('multer');
                server          = http.createServer(app),
                router          = express.Router()
                    .....
                    app.use(function (req, res, next) {
                    res.header("Access-Control-Allow-Methods", "POST, PUT, OPTIONS, DELETE, GET");
                    res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
                    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                    res.header("Access-Control-Allow-Credentials", true);
                    next();
                });


    var storage = multer.diskStorage({
        destination: function (req, file, cb) {
            cb(null, './uploads/')
        },
        filename: function (req, file, cb) {
            console.log("aha " + file.originalname);
            cb(null, file.originalname)
        }
    })


    var upload = multer().single('file')

    //THIS IS MANDATORY, WITHOUT THIS NOW WORK
    app.use(multer({
     storage:storage
     }).single('file'));


              app.use(bodyParser.urlencoded({extended: false}));
              app.use(bodyParser.json());
              app.use(cors());
              app.use(methodOverride());
              app.use(passport.initialize());
              app.use(busboyBodyParser());
              //
              app.use('/api', router);


router.post("/uploadPhoto", function(req, res) {
    console.log(req.file);
    upload(req,res,function(err){
        if(err){
            res.status(500).json({'success':false});
            return;
        }
        res.status(200).json({'success':true});
    });
});

The app.use(multer({storage:storage}).single('file')); appears to be the key. But I pretty new and I dont know why

Also With 'multiple' and .array('file',12) isn't work

I've founded a related question on multer github page with the same problem