1

我按照本教程使用 multer-express 进行文件上传,然后通过 id Scoth.io检索图像。

该设置使用 LokiJS 作为数据库。

所有 API 都可以正常工作,但是当通过 ID 检索多个图像的 API 不适用于多个图像时。大多数获取请求都在服务器上挂起(状态在 Chrome 开发工具的网络面板中挂起)。

一旦处于挂起状态(永远挂起),请求就永远不会完成,服务器就会陷入这种状态。

待处理的网络请求-chrome-dev-tools

通过 Id 检索图像的 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>

实用程序.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 }

4

1 回答 1

1

看来确实有问题loadCollection。初始化后,仅在 index.ts 中从数据库中删除并加载db.loadDatabase一次。loadCollection

索引.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!');
})

实用程序.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 }
于 2019-11-11T12:54:48.350 回答