将文件从 Angular 发送到 Node.js
Send a file from Angular to Node.js
我正在创建一个允许用户上传文件的表单。我在前端使用 Angular,在后端使用 Node.js/MySQL。但是,我收到一个错误。当我尝试将文件从 Angular 发送到 Node.js 时,没有收到文件。我在堆栈溢出的某处读到可以在 http headers 中发送文件。谁能告诉我我做错了什么?这是我的代码:
xxxx.component.html (Angular)
<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 (Angular)
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:\fakepath\testfile.docx
undefined
我尝试了不同的方法,但仍然无法取得进一步的进展。谁能告诉我为什么会出现未定义和假路径错误。
编辑:当我尝试访问文件时,它只打印路径而不是文件。 angular Http 请求只发送文件的路径而不是文件本身。
编辑:再次编辑这个问题,以便有人可以提供帮助。编辑:我尝试过很多不同的事情,但对我来说没有任何效果。 node.js 只是获取文件的路径,而不是文件本身。
文件将不会成为开箱即用请求的一部分;它们必须临时存储在磁盘或内存中 Node.js。尝试类似 multer 的东西:https://medium.com/javascript-in-plain-english/uploading-files-using-multer-on-server-in-nodejs-and-expressjs-5f4e621ccc67
尝试使用 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) {
}
}
有很多方法可以做到这一点。
- 没有任何
npm
包
- 使用
npm i multer
不过,我将讨论第一种方法,而不是使用 multer。
通过angular上传的步骤如下:
- component.html
<input type="file" id="fileuploadPhoto" (change)="onPhotoUpload($event)">
<label for="fileuploadPhoto" class="custom-file-upload">
- 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;
}
}
- 在service.ts中使用post方法传递我们保存为base64字符串的图片
addCustomer(data: Object) {
return this.http.post(environment._customerAPI + '/addCustomer', data)
}
在NodeJS中(基于MVC架构)
- 路线
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config()
}
/* =================================================================================================== */
/* Initialising Express & other dependencies */
/* =================================================================================================== */
const express = require('express');
const cors = require('cors')
const bodyParser = require('body-parser');
/* =================================================================================================== */
/* Data server to handle data transfer & 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)
- 图片上传控制器
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 };
}
我正在创建一个允许用户上传文件的表单。我在前端使用 Angular,在后端使用 Node.js/MySQL。但是,我收到一个错误。当我尝试将文件从 Angular 发送到 Node.js 时,没有收到文件。我在堆栈溢出的某处读到可以在 http headers 中发送文件。谁能告诉我我做错了什么?这是我的代码:
xxxx.component.html (Angular)
<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 (Angular)
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:\fakepath\testfile.docx
undefined
我尝试了不同的方法,但仍然无法取得进一步的进展。谁能告诉我为什么会出现未定义和假路径错误。
编辑:当我尝试访问文件时,它只打印路径而不是文件。 angular Http 请求只发送文件的路径而不是文件本身。 编辑:再次编辑这个问题,以便有人可以提供帮助。编辑:我尝试过很多不同的事情,但对我来说没有任何效果。 node.js 只是获取文件的路径,而不是文件本身。
文件将不会成为开箱即用请求的一部分;它们必须临时存储在磁盘或内存中 Node.js。尝试类似 multer 的东西:https://medium.com/javascript-in-plain-english/uploading-files-using-multer-on-server-in-nodejs-and-expressjs-5f4e621ccc67
尝试使用 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) {
}
}
有很多方法可以做到这一点。
- 没有任何
npm
包 - 使用
npm i multer
不过,我将讨论第一种方法,而不是使用 multer。 通过angular上传的步骤如下:
- component.html
<input type="file" id="fileuploadPhoto" (change)="onPhotoUpload($event)">
<label for="fileuploadPhoto" class="custom-file-upload">
- 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;
}
}
- 在service.ts中使用post方法传递我们保存为base64字符串的图片
addCustomer(data: Object) {
return this.http.post(environment._customerAPI + '/addCustomer', data)
}
在NodeJS中(基于MVC架构)
- 路线
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config()
}
/* =================================================================================================== */
/* Initialising Express & other dependencies */
/* =================================================================================================== */
const express = require('express');
const cors = require('cors')
const bodyParser = require('body-parser');
/* =================================================================================================== */
/* Data server to handle data transfer & 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)
- 图片上传控制器
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 };
}