Javascript 使用multer/Angular上传文件
错误:多部分:未找到边界 我想添加包含以下文字文件的文件: 这是我的服务: src/app/services/web.service.tsJavascript 使用multer/Angular上传文件,javascript,angular,express,multer,multer-gridfs-storage,Javascript,Angular,Express,Multer,Multer Gridfs Storage,错误:多部分:未找到边界 我想添加包含以下文字文件的文件: 这是我的服务: src/app/services/web.service.ts import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; const httpOptions = { headers: new HttpHeaders({ 'Content-Type':
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'multipart/form-data'
})
}
@Injectable({
providedIn: 'root'
})
export class WebService {
devUri:string = 'http://localhost:4000';
constructor(private http:HttpClient) { }
post(uri:string, object: Object){
console.log(object);
return this.http.post(`${this.devUri}/${uri}`, object, httpOptions);
}
}
它显示错误:多部分:未找到边界
在有人写“只需删除‘内容类型’:‘多部分/表单数据’之前,它会起作用,但不会!
当我删除它时,我的req.files=[](还有一些变量,其中它等于未定义)。
这是我的路线(没有满,但不需要更多):
routes/api/messages.js
const { initStorage, initUpload } = require('../../modules/multerModule');
const conn = mongoose.connection;
Grid.mongo = mongoose.mongo;
// Init gfs
let gfs;
conn.once('open', () => {
// Init stream
gfs = Grid(conn.db);
gfs.collection(collectionName);
});
const collectionName = 'messages';
const bucketName = 'messages';
const storage = initStorage(conn, bucketName);
const upload = initUpload(storage);
router.post('/', upload.any(), (req, res) => {
console.log(req.files);
console.log(req.body);
...
}
以下是我在multerModule中的函数(它都适用于react/redux、app,但不适用于Angular):
模块/multerModule.js:
const path = require('path');
const multer = require('multer');
const crypto = require('crypto');
const GridFsStorage = require('multer-gridfs-storage');
// Create storage engine
const initStorage = (conn, bucketName) => new GridFsStorage({
db: conn,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: bucketName
};
resolve(fileInfo);
});
});
}
});
// Create upload module
const initUpload = (storage) => multer({
storage: storage,
fileFilter: function (req, file, callback) {
const ext = path.extname(file.originalname);
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return callback(new Error('Only images are allowed'))
}
callback(null, true)
}
});
module.exports = { initStorage, initUpload };
当然,稍后当我尝试使用req.files(destructurize或其他任何内容)时,会出现错误,因为它是未定义或空数组。在req.body中,还会显示messages字段:
[Object: null prototype] {
messages: '[object File]',
content: 'dsada',
path: 'undefined',
fileImage: 'true'
}
最后两项是server.js和onSubmit函数:
server.js
...
const bodyParser = require('body-parser');
// #6 Initialize an Express application
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
app.use(bodyParser.json({limit: '50mb', extended: true}));
const db = process.env.mongoURI;
// Connect to Mongo
mongoose
.connect(db, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false }) // Adding new mongo url parser
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
...
OnSubmit函数:
src/app/components/Message/add Message/add-Message.ts
onSubmit() {
if( this.fileImage){
const message = new FormData();
console.log(this.files[0]);
message.append('messages', this.files);
console.log(typeof(JSON.stringify(this.fileImage)));
message.append('content', this.content);
message.append('fileImage', JSON.stringify(this.fileImage));
this.addMessage.emit(message);
}
else{
const message = {
content: this.content,
fileImage: this.fileImage,
path: this.path
}
this.addMessage.emit(message);
}
}
尝试了几次之后,我遇到了另一个错误(现在我没有在HttpClient模块中包含httpOptions,并且附加到FormData()的文件数据与react redux/node app中的相同):
问题是相同的代码在redux应用程序中正常工作,但在angular应用程序中不正常。好的,我在这里输入console.log时发现了一些问题:
conn.once('open', () => {
// Init stream
gfs = Grid(conn.db);
gfs.collection(collectionName);
});
const collectionName = 'messages';
const bucketName = 'messages';
console.log(conn);
...
我发现了一个不同点:
在angular应用程序中,我发现:
models: { user: Model { user } }
我有三个模型:用户、帖子和消息
在react应用程序上,我发现:
models: {
announcement: Model { announcement },
user: Model { user },
slide: Model { slide },
content: Model { content },
insurance: Model { insurance },
contact: Model { contact }
}
这是正确的,所以看起来我的存储并没有包括所有型号的路由。
我不知道为什么,但似乎这就是问题所在。
modelSchemas属性也是如此。
即使我对这个路由(app.use(/auth))进行注释,它仍然只包括userSchema和UserModel
连接到server.js后,我记录了“承诺”
并且只得到一个模型和模式(即使我有三个模型:post、user、message):
Promise{}
国家联系{
基地:猫鼬{
连接:[[循环]],
模型:{user:Model{user},
模型架构:{user:[Schema]},
选项:{pluralization:true,[Symbol(mongoose:default)]:true},
_多元化:[功能:多元化],
Schema:[函数:Schema]{
保留:[对象:空原型],
类型:[对象],
ObjectId:[功能]
},
型号:[功能],
插件:[[Array]、[Array]、[Array]、[Array]、[Array]]
},
收藏:{
用户:NativeCollection{
集合:null,
承诺:[功能:承诺],
_关闭:错误,
选项:[对象],
名称:'用户',
collectionName:'用户',
康涅狄格州:[环线],
队列:[],
缓冲区:对,
发射器:[事件发射器]
}
},
模型:{user:Model{user},
配置:{autoIndex:true,useCreateIndex:true,useFindModify:false},
复制品:假,
选项:null,
其他数据库:[],
关系数据库:{},
状态:[对象:空原型]{
“0”:“已断开连接”,
“1”:“已连接”,
“2”:“正在连接”,
“3”:“断开连接”,
“99”:“未初始化”,
断开连接:0,
联系:1,,
连接:2,
断开连接:3,
未初始化:99
},
_重新编制日期:2,
_这是错误的,
_他说:错,
插件:[],
id:0,
_听:错,
_connectionString:'抱歉,但无法传递:)',
_连接选项:{
useNewUrlParser:true,
useUnifiedTopology:正确,
promiseLibrary:[功能:Promise],
driverInfo:{name:'Mongoose',版本:'5.10.3'}
},
客户:MongoClient{
_事件:[对象:空原型]{},
_事件提示:0,
_maxListeners:未定义,
s:{
url:'抱歉,但无法传递:)',
选项:[对象],
promiseLibrary:[功能:Promise],
dbCache:Map{},
会话:设置{},
writeConcern:未定义,
命名空间:[MongoDBNamespace]
},
[符号(kCapture)]:false
},
“$initialConnection”:承诺{},
然后:[函数],
catch:[函数],
_事件:[对象:空原型]{
打开:[函数:绑定onceWrapper]{侦听器:[函数]}
},
_活动地点:1
I just console.log server.js的每个部分和路由(如gfs或conn.db)与我在React项目中的操作相同,但它仍然向我显示一个错误:错误:数据库连接必须打开才能在GridFSStorage中存储文件。\u handleFile如果有人有解决方案,请提供帮助。
models: {
announcement: Model { announcement },
user: Model { user },
slide: Model { slide },
content: Model { content },
insurance: Model { insurance },
contact: Model { contact }
}
// Connect to Mongo
const promise = mongoose
.connect(db, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false }) // Adding new mongo url parser
.then(() => console.log('MongoDB Connected...'))
.catch(err => console.log(err));
console.log(promise);
Promise { <pending> }
NativeConnection {
base: Mongoose {
connections: [ [Circular] ],
models: { user: Model { user } },
modelSchemas: { user: [Schema] },
options: { pluralization: true, [Symbol(mongoose:default)]: true },
_pluralize: [Function: pluralize],
Schema: [Function: Schema] {
reserved: [Object: null prototype],
Types: [Object],
ObjectId: [Function]
},
model: [Function],
plugins: [ [Array], [Array], [Array], [Array], [Array] ]
},
collections: {
users: NativeCollection {
collection: null,
Promise: [Function: Promise],
_closed: false,
opts: [Object],
name: 'users',
collectionName: 'users',
conn: [Circular],
queue: [],
buffer: true,
emitter: [EventEmitter]
}
},
models: { user: Model { user } },
config: { autoIndex: true, useCreateIndex: true, useFindAndModify: false },
replica: false,
options: null,
otherDbs: [],
relatedDbs: {},
states: [Object: null prototype] {
'0': 'disconnected',
'1': 'connected',
'2': 'connecting',
'3': 'disconnecting',
'99': 'uninitialized',
disconnected: 0,
connected: 1,
connecting: 2,
disconnecting: 3,
uninitialized: 99
},
_readyState: 2,
_closeCalled: false,
_hasOpened: false,
plugins: [],
id: 0,
_listening: false,
_connectionString: 'Sorry, but cannot pass :)',
_connectionOptions: {
useNewUrlParser: true,
useUnifiedTopology: true,
promiseLibrary: [Function: Promise],
driverInfo: { name: 'Mongoose', version: '5.10.3' }
},
client: MongoClient {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
s: {
url: 'sorry, but cannot pass :)',
options: [Object],
promiseLibrary: [Function: Promise],
dbCache: Map {},
sessions: Set {},
writeConcern: undefined,
namespace: [MongoDBNamespace]
},
[Symbol(kCapture)]: false
},
'$initialConnection': Promise { <pending> },
then: [Function],
catch: [Function],
_events: [Object: null prototype] {
open: [Function: bound onceWrapper] { listener: [Function] }
},
_eventsCount: 1