Multer анализирует данные составной формы при использовании почтальона, но не анализирует данные составной формы в запросе от клиентского приложения - PullRequest
0 голосов
/ 04 июля 2019

Я пытаюсь использовать multer для поддержки загрузки файлов из моего клиента приложения реакции на мой узел / экспресс-бэкэнд.

Для некоторого фона я использовал почтальон 6.7.2, узел 8.11.1, экспресс 4.16.3 и мультитер 1.4.1. После обучения я мог использовать почтальон для входа в req.body и просмотра записей в форме данных; как я могу войти req.body и req.file в обработчик маршрута (), и файл даже сохраняет. Но когда я пытаюсь отправить запрос из моего приложения реагирования, req.body регистрируется как {}, а req.file регистрируется как неопределенное.

Это мой файл app.js.

if (process.env.NODE_ENV !== 'production') {
  require('dotenv').config();
}

const path = require('path');
const port = process.env.PORT || 4000;
const mongoURI =
  process.env.NODE_ENV !== 'production'
    ? 'mongodb://localhost/mern2'
    : process.env.MONGODB_URI;

// node server dependencies
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');

const app = express();
const routes = require('./controllers/index');
// Server setup for MongoDB
mongoose.connect(mongoURI);
mongoose.set('useCreateIndex', true);
mongoose.Promise = global.Promise;

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

// use router handlers
app.use('/api', routes);


// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  // res.render('error');
});

app.get("*", (req, res) => {
    res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});

app.listen(port, () =>
  console.log('LISTENING FOR REQUESTS ON PORT ' + port)
);

это мой файл маршрутов (controllers / index.js)

const express = require('express')
  , router = express.Router();

router.use('/admin', require('./admin'));

module.exports = router;

и это мой обработчик маршрута, (admin.js)

router.patch('/panel', upload.single('panelImage'), (req, res) => {
  console.log('req.headers', req.headers);
  console.log('req.body', req.body);
  console.log('req.file', req.file);
  res.send({message: 'success'});
});

на стороне реакции у меня есть функция patchFileReq, которая похожа на обычный запрос исправления, принимает, что добавляет заголовок данных составной формы и отправляет объект FormData в качестве тела.

backendUtils.js

export function patchFileReq (url, body, token) {
  var formData = new FormData();
  Object.keys(body).forEach((key) => {
    if(body[key] instanceof File){
      formData.append(key, body[key], body[key].name);
    }
    else {
      formData.append(key, body[key]);
    }
  });
  for (var key of formData.entries()) {
    console.log(key[0] + ' ' + key[1]);
  }
  const headers = prepareFormDataHeaders(prepareAuthorizationHeaders(token));
  return Observable.ajax.patch(url, formData, headers)
    .map(parseAjaxResponse)
    .catch(parseAjaxError);
}

вот вывод admin.js, когда я использую почтальон:

*** file *** { fieldname: 'testImage',
  originalname: 'bsn_2R_80_test.png',
  encoding: '7bit',
  mimetype: 'image/png' }
req.headers { 'content-type': 'multipart/form-data; boundary=--------------------------069393334143100418462268',
  'cache-control': 'no-cache',
  'postman-token': 'd289023d-956e-4d03-a0b4-073e6ffbd346',
  'user-agent': 'PostmanRuntime/7.6.0',
  accept: '*/*',
  host: 'localhost:4000',
  'accept-encoding': 'gzip, deflate',
  'content-length': '332255',
  connection: 'keep-alive' }
req.body { testfield: 'testvalue' }
req.file { fieldname: 'testImage',
  originalname: 'bsn_2R_80_test.png',
  encoding: '7bit',
  mimetype: 'image/png',
  destination: './uploads',
  filename: 'bsn_2R_80_test.png',
  path: 'uploads/bsn_2R_80_test.png',
  size: 331918 }

А вот вывод для admin.js, когда я использую свое приложение реакции

req.headers { 'x-forwarded-host': 'localhost:3000',
  'x-forwarded-proto': 'http',
  'x-forwarded-port': '3000',
  'x-forwarded-for': '127.0.0.1',
  'accept-language': 'en-US,en;q=0.9,pl-PL;q=0.8,pl;q=0.7',
  'accept-encoding': 'gzip, deflate, br',
  referer: 'http://localhost:3000/admin-panel/doors-and-sidelites',
  accept: '*/*',
  'content-type': 'multipart/form-data; boundary=--------------------------833495845447745121323852',
  'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
  'x-requested-with': 'XMLHttpRequest',
  origin: 'http://localhost:4000',
  authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVjYzEzMGI5MmM2MjVmM2ZmMWRlNjk3OCIsImVtYWlsIjoiZ3JlZ29yeS50ZXJsZWNraUBnbWFpbC5jb20iLCJpYXQiOjE1NjIyNjc5MTgsImV4cCI6MTU2MjM1NDMxOH0.pb9GfYjiwQRK8TInsbhf1565ENnSBnsoELClLH1SXB0',
  'content-length': '372484',
  connection: 'close',
  host: 'localhost:4000' }
req.body {}
req.file undefined

Чуть выше, где написано

req.body {}
req.file undefined

Где я не вижу того, чего ожидаю; Я ожидаю увидеть тот же результат для req.body и req.file, что и при использовании почтальона, который может каким-то образом взять тело и файл.

Редактировать: я добавляю больше кода переднего конца.

epics / admin.js это мое эпическое промежуточное ПО

...

import {adminSavePanelRequest} from '../../lib/backend;

const adminSavePanelSuccess = (payload) => ({payload, type: ADMIN_SAVE_PANEL_SUCCESS});
const adminSavePanelFailure = (payload) => ({payload, type: ADMIN_SAVE_PANEL_FAILURE});
const adminSavePanel = (action$, store) =>
  action$.ofType(ADMIN_SAVE_PANEL)
    .flatMap(() => {
      const state = store.getState();
      var serverPayload = {};
      serverPayload = state.getIn(['adminPanel', 'doorsForm']).toJS();
      return adminSavePanelRequest(serverPayload)
      .map(adminSavePanelSuccess)
      .catch((error) => Rx.Observable.of(error)
        .do((error) => {
        console.log(`Error: ${error}`);
        })
        .map(adminSavePanelFailure)
      )
    });

...

backend.js

import patchFileReq from './backendUtils';

export function adminSavePanelRequest(payload){
  return patchFileReq('/api/admin/panel', payload, getAuthToken());
}

редукторы / админ / model.js

export const DoorsForm = new Record({
  _id: '',
  name: '',
  material: '',
  testImage: ''
});

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...