简体   繁体   中英

File Upload from Angular to NodeJS Backend to NodeJS API

I'm having troubles forwarding files from my NodeJS web backend to my NodeJS API. I'm not quite sure what I'm missing. I just know that there are no files found in the request when it gets to the API. Hopefully someone can clarify what I am missing here.

API app.js

var routes = require('./routes/index');
app.use('/api', routes.api);

API /routes/index.js

exports.api = require('./api');

API /routes/api.js

const express = require('express');
const router = express.Router();
const multer = require('multer');
const upload = multer();

router.post("/file/upload", upload.any(), (req, res) => {
  console.log("==> inside file upload <===");
  console.log(req.files ? req.files.length : -1, " => num files found in request");
  res.status(200).send("File Uploaded");
});

module.exports = router;

API Console Output

==> inside file upload <===
0  => num files found in request
POST /api/file/upload 200 19.037 ms - 13

Angular HTML

<h1 class="text-center">
  Test File Upload
</h1>

<div class="row">
  <div class="col-8 offset-4">

    <form #frmUpload method="POST" action="/api/file/upload" enctype="multipart/form-data">
      <input #inFile type="file" name="inFile" (change)="submitUpload()" />
    </form>
  
  </div>
</div>

Angular TS

@ViewChild("frmUpload", {static: false}) frmUpload: ElementRef;
@ViewChild("inFile", {static:false}) inFile: ElementRef;


submitUpload() {
    const _form: HTMLFormElement = this.frmUpload.nativeElement;
    _form.submit();
    setTimeout(() => {
        this.inFile.nativeElement.value = "";
    }, 500);
}

NodeJS Web Backend app.js

var indexRouter = require('./routes/index');
app.use('/', indexRouter);

NodeJS Web Backend /routes/index.js

const express = require('express');
const router = express.Router();
const Path = require('path');
const multer = require('multer');
const upload = multer();
const http = require('http');
const FormData = require('form-data');

router.post('/api/file/upload', upload.any(), (req, res) => {
  console.log(req.files ? req.files.length : -1, " => num files found in request");
  const { headers, files } = req;
  const { buffer, originalname: filename } = files[0];
  const formData = new FormData();
  formData.append('file', buffer, { filename });
  const postReq = http.request({
    host: "localhost",
    port: 3000,
    path: "/api/file/upload",
    headers:  formData.getHeaders(),
    method: "POST"
  }, (response) => {
    console.log("api has responded");
  });
  postReq.end(); 
  res.send("<p>File uploaded</p><div style='margin:10px;'><a href='/'>Go Back</a></div>");
});

/* GET home page. */
router.get('/', function(req, res, next) {
  console.log("..... Render Angular ......");
  res.sendFile(Path.resolve('../angular/dist/angular/index.html'));
});

module.exports = router;

NodeJS Web Backend Console Output

1  => num files found in request
POST /api/file/upload 200 4.226 ms - 75
api has responded

Take a look at the API console output. See how it says "0 files found." That is the issue I am having. Look at the Web Backend and you will see the file is there before I attempt to forward it to the API. Any ideas on what I've done wrong here?

You actually need to send the data of your form with a pipe.

  const postReq = http.request({
    host: "localhost",
    port: 3000,
    path: "/api/file/upload",
    headers:  formData.getHeaders(),
    method: "POST"
  }, (response) => {
    console.log("api has responded");
  });
  formData.pipe(postReq);   // <---- add this

You don't need the postReq.end() .

To debug:

If you actually wanted to see what you're sending to the API, you could send your form data to a file. It works similarly.

const fs = require('fs');

const writeStream = fs.createWriteStream('./debug.log');
formData.pipe(writeStream);

The content of the file should look like

----------------------------132413245123412341234
Content-Disposition: form-data; name="filename"; filename="filename.ext"
Content-Type: some/mimetype
... followed by the data
 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM