Почему тело запроса пустое, а статус ответа-404?

#node.js #express

Вопрос:

Я пытаюсь создать веб-приложение с использованием шаблона MVC, но у меня проблема с последующим запросом на «http://localhost:5000/api/device»: попытка отправки запроса почтальоном

Проблема возникает только при запросе POST, ПОЛУЧИТЬ запрос в порядке: получить запрос

Код:

index.js

 const express = require('express')
const sequelize = require('./db')
require('dotenv').config();
const path = require('path')

const models = require('./models/models')
const cors = require("cors")

const app = express();
const router = require('./routes/index')
const fileUpload = require('express-fileupload')

const errorHandler = require('./milddleware/ErrorHandlingMiddleware')
app.use(cors())

app.use(express.json())
app.use(express.static(path.resolve(__dirname, 'static')))

app.use(fileUpload({}))

app.use('/api', router)

app.use(errorHandler)
const PORT = process.env.PORT || 5000;
const db_start = async ()=>
{
    try
    {
        await sequelize.authenticate();
        await sequelize.sync();
        app.listen(PORT, ()=>{console.log(`Server started on port ${PORT}`)})
    }
    catch (e)
    {
        console.log(e);
    }
}

db_start()
 

routes/index.js

 const  Router  = require('express')

const router = new Router();

const deviceRouter = require('./deviceRouter')
const typeRouter = require('./typeRouter')
const brandRouter = require('./brandRouter')
const userRouter = require('./userRouter')

router.use('/user', userRouter)
router.use('/device', deviceRouter)
router.use('/brand', brandRouter)
router.use('/type', typeRouter)

module.exports = router
 

routes/deviceRouter.js

 const  Router  = require('express')
const DeviceController = require('../controllers/deviceController')

const router = new Router();

router.post('/', DeviceController.create)
router.get('/', DeviceController.getAll)
router.get('/:id', DeviceController.getOne)
module.exports = router
 

controllersdeviceController.js

 const uuid = require('uuid')
const path = require('path')
const {Device} = require('../models/models')
const ApiError = require("../errors/ApiError")

class DeviceController
{
    async create(req, res, next)
    {
        console.log(req);
      try{  
        const {name, price, brandId, typeId, info} = req.body;
        const {img} = req.files;
        let fileName = uuid.v4()   ".jpg";
        img.mv(path.resolve(__dirname, '..', 'static', fileName));
        
        const device = await Device.create({name, price, brandId, typeId, img: fileName});
        return res.json(device);
        }
        catch(e)
        {
            next(ApiError.badRequest(e.message));
        }

    }

    async getAll(req, res)
    {
        const {brandId, typeId} = req.query
        let devices;
        if(!brandId amp;amp; !typeId)
        {
            devices = await Device.findAll()
        }
        if(brandId amp;amp; !typeId)
        {
            devices = await Device.findAll({where: {brandId}})

        }
        if(!brandId amp;amp; typeId)
        {
            devices = await Device.findAll({where: {typeId}})
        }
        if(brandId amp;amp; typeId)
        {
            devices = await Device.findAll({where: {brandId,typeId}})
        }
        return res.json(devices)
            
    }

    async getOne(req,res)
    {
        
    }
}

module.exports = new DeviceController()
 

Я зарегистрировал запрос и увидел, что тело запроса оказалось пустым и req.files не определено.
Я сравнил эти маршрутизатор и контроллер с другими и не обнаружил различий в структуре.
Что я делаю не так?

Ответ №1:

Вы не можете извлекать файлы form-data непосредственно из req.files .

Используйте formidable (это пакет npm) parse form-data и легко работайте с ним. Вот шаги:

  1. Бежать npm install formidable .
  2. Импортируйте formidable и fs упакуйте в свой сценарий контроллера с помощью:
     const formidable = require('formidable')
    const fs = require('fs');
     
  3. Измените свое create function с помощью этого:
     async create(req, res, next) {
        let form = new formidable.IncomingForm()
        form.keepExtensions = true
    
        form.parse(req, async (err, fields, files) => {
            // console.log('err', err)
            // console.log('fields', fields)
    
            if (err) {
                next(ApiError.badRequest(err));
                return;
            }
    
            const { name, price, brandId, typeId, info } = fields; // <-- fields contain all your text data. it's like req.body
            const { img } = files; // <-- it should work now!
            let fileName = uuid.v4()   ".jpg";
            fs.writeFileSync(path.resolve(__dirname, '..', 'static', fileName), img);
    
            const device = await Device.create({ name, price, brandId, typeId, img: fileName });
            return res.json(device);
        }
    }
     

Комментарии:

1. Я получил это: prnt.sc/1sb4a2x и моя просьба в «почтальоне» замирает.

2. Я обновил свой код. взглянуть. повторите все шаги еще раз.