Node-LokiJS:并非所有 get 请求都已完成,请求状态永远未决?
Node-LokiJS: not all get requests are fulfilled, request status is forever pending?
我按照本教程使用 multer-express 上传文件,然后通过 id Scoth.io 检索图像。
设置使用 LokiJS 作为数据库。
所有 API 都可以正常工作,但是当 API 按 ID 检索多张图片时,它对多张图片不起作用。大多数获取请求在服务器上处于挂起状态(状态在 Chrome 开发工具的网络面板中处于挂起状态)。
一旦处于挂起状态(永远挂起),请求就永远不会完成,并且服务器会卡在该状态。
API 通过 Id 检索图像
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!');
})
Index.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 }
看来 loadCollection
确实有问题。
从 loadCollection
中删除 db.loadDatabase
并仅在 index.ts 初始化数据库后加载一次数据库。
index.ts
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' })
db.loadDatabase({});
// 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!');
})
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 => {
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 }
我按照本教程使用 multer-express 上传文件,然后通过 id Scoth.io 检索图像。
设置使用 LokiJS 作为数据库。
所有 API 都可以正常工作,但是当 API 按 ID 检索多张图片时,它对多张图片不起作用。大多数获取请求在服务器上处于挂起状态(状态在 Chrome 开发工具的网络面板中处于挂起状态)。
一旦处于挂起状态(永远挂起),请求就永远不会完成,并且服务器会卡在该状态。
API 通过 Id 检索图像
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!');
})
Index.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 }
看来 loadCollection
确实有问题。
从 loadCollection
中删除 db.loadDatabase
并仅在 index.ts 初始化数据库后加载一次数据库。
index.ts
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' })
db.loadDatabase({});
// 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!');
})
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 => {
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 }