Я следовал этому руководству при загрузке файлов с помощью multer-express, а затем извлекал изображение по идентификатору Scoth.io .
. В качестве базы данных для установки используется LokiJS.
ВсеAPI работает хорошо, однако, когда API для получения нескольких изображений по идентификатору не работает для нескольких изображений. Большинство запросов на получение ожидают на сервере (статус находится в состоянии ожидания на панели «Сеть» инструментов Chrome Dev).
Запросы никогда не выполняются один раз в состоянии ожидания (навсегда ожидают), и сервер застревает в этом.
API для получения изображения по идентификатору
app.get('/images/:id', async (req, res) => {
try {
const col = await loadCollection(COLLECTION_NAME, db);
const result = col.get(req.params.id);
if (!result) {
res.sendStatus(404);
return;
};
res.setHeader('Content-Type', result.mimetype);
fs.createReadStream(path.join(UPLOAD_PATH, result.filename)).pipe(res);
} catch (err) {
res.sendStatus(400);
}
})
Index.ts (все API)
import * as express from 'express'
import * as multer from 'multer'
import * as cors from 'cors'
import * as fs from 'fs'
import * as path from 'path'
import * as Loki from 'lokijs'
import { loadCollection, imageFilter } from './utils'
//setup
const DB_NAME = 'db.json'
const COLLECTION_NAME = 'images'
const UPLOAD_PATH = 'uploads'
const upload = multer({ dest: `${UPLOAD_PATH}/`, fileFilter: imageFilter }) //MULTER CONFIG
const db = new Loki(`${UPLOAD_PATH}/${DB_NAME}`, { persistenceMethod: 'fs' })
// app
const app = express();
app.use(cors());
app.get('/', (req, res) => {
res.json({responseText : 'Server running successfully'})
})
//Upload Single
app.post('/fileUpload', upload.single('file'), async (req, res) => {
try {
const col = await loadCollection(COLLECTION_NAME, db)
const data = col.insert(req.file)
db.saveDatabase()
res.send({id: data.$loki, fileName: data.filename, originalName: data.originalname })
} catch (err) {
res.sendStatus(400)
}
})
//Upload Multiple
app.post('/photos/upload', upload.array('photos', 12), async (req, res) => {
try {
const col = await loadCollection(COLLECTION_NAME, db)
const data = [].concat(col.insert(req.files))
db.saveDatabase()
res.send(data.map(x => ({ id: x.$loki, fileName: x.filename, originalName: x.originalname })));
} catch (err) {
res.sendStatus(400)
}
})
//Retrieve Image
app.get('/images', async (req, res) => {
try {
const col = await loadCollection(COLLECTION_NAME, db)
res.send(col.data)
} catch(err) {
res.sendStatus(400)
}
})
// Retrieve Image by Id
app.get('/images/:id', async (req, res) => {
try {
const col = await loadCollection(COLLECTION_NAME, db)
const result = col.get(parseInt(req.params.id))
if(!result) {
res.sendStatus(404)
return;
}
res.setHeader('Content-Type', result.mimetype);
fs.createReadStream(path.join(UPLOAD_PATH, result.filename)).pipe(res)
} catch(err) {
res.sendStatus(400)
}
})
app.listen(3000, function () {
console.log('listening on port 3000!');
})
Индекс.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Fetch Image (NodeJS-LokiJS API) - Example</title>
<style>
.photo {
width: 100px;
display: block;
margin-bottom: 5px;
border: 2px solid black;
}
</style>
</head>
<body>
<h1>HTML Example</h1>
<p>
JPEG:<br>
<img class="photo" src="http://localhost:3000/images/1">
<img class="photo" src="http://localhost:3000/images/2">
<img class="photo" src="http://localhost:3000/images/3">
<img class="photo" src="http://localhost:3000/images/4">
<img class="photo" src="http://localhost:3000/images/5">
<img class="photo" src="http://localhost:3000/images/6">
</p>
</body>
</html>
utils.ts
import * as del from 'del'
import * as Loki from 'lokijs'
const loadCollection = function (colName, db: Loki): Promise<Loki.Collection<any>> {
return new Promise(resolve => {
db.loadDatabase({}, _=> {
const _collection = db.getCollection(colName) || db.addCollection(colName)
resolve(_collection)
})
})
}
const imageFilter = function (req, file, cb) {
// accept image only
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
return cb(new Error('Only image files are allowed!'), false);
}
cb(null, true);
}
export { imageFilter, loadCollection }