Отправить файл из Angular в Node.js

#node.js #angular #angular-fullstack

#node.js #угловой #angular-полный пакет

Вопрос:

Я создаю форму, позволяющую пользователям загружать свои файлы. Я использую Angular для интерфейса и Node.js / MySQL для серверной части. Однако я получаю сообщение об ошибке. Когда я пытаюсь отправить файл из Angular в Node.js , файл не будет получен. Я где-то читал о переполнении стека, что можно отправить файл в http-заголовках. Кто-нибудь может сказать мне, что я делаю не так? Вот мой код:

xxxx.component.html (Угловой)

 <div class="input-group">
    <div class="input-group-prepend">
 </div>
 <div class="custom-file">
   <input type="file" class="custom-file-input" [(ngModel)] = "fU" name = 
    "FileUpload" id="inputGroupFile01"
     aria-describedby="inputGroupFileAddon01" required>
     <label class="custom-file-label" for="inputGroupFile01">Choose file</label>
 </div>
</div>
 

xxxx.component.ts (угловой)

 private onCreatePosts(form: NgForm)
{
    this.http.post('http://localhost:3000/post', form.value)
    .subscribe(responseData => {
      console.log(responseData);
    }
    ,error => {
      this.connectionToServerFailed = true;
    });
 }
 

Node.js

 router.post("/post", (req, res) =>{
var fileupload = req.body.FileUpload;
console.log(fileupload);
console.log(fileupload.name);
})
 

Вот результат, который я получаю, когда пытаюсь загрузить файл:

C:fakepathtestfile.docx
неопределенный

Я пробовал разные вещи, но все еще не смог продвинуться дальше. Кто-нибудь может сказать мне, почему я получаю эту ошибку undefined и fakepath.

РЕДАКТИРОВАТЬ: когда я пытаюсь получить доступ к файлу, он выводит только путь, а не файл. Угловой Http-запрос отправляет только путь к файлу, а не сам файл. РЕДАКТИРОВАТЬ: снова отредактируйте этот вопрос, чтобы кто-нибудь мог помочь. РЕДАКТИРОВАТЬ: я пробовал работать с множеством разных вещей, но у меня ничего не получается. В node.js получает только путь к файлу, а не сам файл.

Ответ №1:

Файлы не будут частью запроса «из коробки»; они должны быть временно сохранены на диске или в памяти в Node.js . Попробуйте что-то вроде multer: https://medium.com/javascript-in-plain-english/uploading-files-using-multer-on-server-in-nodejs-and-expressjs-5f4e621ccc67

Ответ №2:

Попробуйте использовать FormData

 private onCreatePosts(form: NgForm)
{
    const fd = new FormData();
    fd.append("file", file, file.name)               //your file, file name
    this.http.post('http://localhost:3000/post', fd)
    .subscribe(responseData => {
      console.log(responseData);
    }
    ,error => {
      this.connectionToServerFailed = true;
    });
 }
 

В node.js

 const fileupload = async (req, res) => {
    try {
        let form = new IncomingForm();
        form.parse(req, (err, field, files) => {
            fs.readFile(files.file.path, async (err, data) => {
                 // data is your file data
            })
        })
    }
    catch (e) {

    }
}
 

Комментарии:

1. Зачем вам читать файл в вашем node.js когда вы хотите его сохранить? Я хочу сохранить этот файл в node.js после получения его от Angular.

2. Мы отправляем форму из внешнего интерфейса, поэтому я использовал IncomingForm, чтобы получить форму из внешнего интерфейса (angular) и проанализировать ее, чтобы получить данные формы

3. У меня уже есть форма, в которую я беру другие входные данные, я хочу добавить опцию добавить файл в эту существующую форму. Я пробовал метод, описанный выше, он не работает. Он по-прежнему выводит только путь, а не сам файл.

Ответ №3:

Есть много способов сделать это.

  1. Без каких-либо npm пакетов
  2. Использование npm i multer

Тем не менее, я буду обсуждать 1-й метод, а не использовать multer. Шаги для загрузки через angular следующие:

  1. component.html
 <input type="file" id="fileuploadPhoto" (change)="onPhotoUpload($event)">
<label for="fileuploadPhoto" class="custom-file-upload">
 
  1. component.ts
 onPhotoUpload(e) {
    var file = e.dataTransfer ? e.dataTransfer.files[0] : e.target.files[0];
    var pattern = /image-*/;
    var reader = new FileReader();
    if (!file.type.match(pattern)) {
      alert('invalid format');
      return;
    }
    reader.onload = this._setUploadPhoto.bind(this);
    reader.readAsDataURL(file);
  }
 
   _setUploadPhoto(e) {
    let reader = e.target;

    const result = reader.result;
    // this.openSnackBar(result.length,"OK")
    if (!result) {
      this.openSnackBar("Cannot read", "OK")
      this.imageSrcPhoto = '';
    }
    if (result.length > 400000) {
      this.openSnackBar("File size should be less than 300KB", "OK")
      this.imageSrcPhoto = '';
    }
    else {
      this.imageSrcPhoto = reader.result;
    }
  }
 
  1. В service.ts используйте метод post для передачи изображения, которое мы сохранили как строку base64
   addCustomer(data: Object) {
    return this.http.post(environment._customerAPI   '/addCustomer', data)
  }
 

В NodeJS (на основе архитектуры MVC)

  1. Маршруты
 if (process.env.NODE_ENV !== 'production') {
    require('dotenv').config()
}

/* =================================================================================================== */
/*                              Initialising Express amp; other dependencies                              */
/* =================================================================================================== */

const express = require('express');
const cors = require('cors')
const bodyParser = require('body-parser');


/* =================================================================================================== */
/*                          Data server to handle data transfer amp; processing                           */
/* =================================================================================================== */

const app = express();

app.use(cors());

app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    // res.setHeader('Content-Type', 'application/x-www-form-urlencoded')
    next();
});

app.use(bodyParser.json({ limit: "5mb" }));

app.use(express.urlencoded({ extended: false }))

const PORT = process.env.PORT;

app.listen(PORT, () => {
    console.log(`Server listening on ${PORT}`);
});
const custRoutes = require('./routes/customer');
app.use('/customer', custRoutes);
router.post('/addCustomer',cust.addCustomer)
 
  1. Контроллер загрузки изображений
 const fs = require("fs");

module.exports.imageUpload = (imgArray, imgName, foldername, misc = null) => {
    const IMG_PATH = process.env.ASSETS_DIR
    var dir = IMG_PATH   '/customer/';
    console.log(dir)
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir);
    }

    dir  = foldername   '/';

    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir);
    }

    var fullImageName;
    var Base64Data;
    var imagePathArray = [];

    imgArray.forEach(img => {
        fullImageName = dir   imgName;
        fullImageName  = '_'   img.Idtype;
        fullImageName  = '.png'

        imagePathArray.push(fullImageName)
        Base64Data = img.imageUrl.replace(/^data:image/[a-z] ;base64,/, "");

        fs.writeFile(fullImageName, Base64Data, 'base64', function (err) {
            return { 'status': false, 'path': null };
        });
    });

    return { 'status': true, 'path': imagePathArray };
}