I’m trying to do a server with node.js, express and multer to upload some files in a POST form-data multipart, but I’m facing the problem that when I’m testing the request POST upload-collection the server returns me “Cannot GET /upload-collection” but I haven’t a GET function defined.
What is wrong? What I’ve to do? I’m testing with postman.
app.js
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const statusRouter = require('./routes/status');
const uploadCollectionRouter = require('./routes/upload_collection');
const errorHandler = require('./error_handler');
const requestTimeout = require('./request_timeout');
const app = express();
const port = process.env.PORT || 8443;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
...
// Middleware de timeout
app.use(requestTimeout);
// Rutas
app.use('/status', statusRouter); // Ruta para verificar el estado de la conexión del servidor
app.use('/upload-collection', uploadCollectionRouter);
// ERROR HANDLER MIDDLEWARE (Last middleware to use)
app.use(errorHandler)
// Crear el servidor pero no iniciarlo aún
const server = app.listen(port, () => {
console.log(`░░░▒▒▒▓▓▓ Inicializando...`);
console.log(`░░░▒▒▒▓▓▓ Abriendo puerto ${port}...`);
});
// Escuchar el evento 'listening' para saber cuándo el servidor está activo
server.on('listening', () => {
const serverAddress = server.address();
const address = (serverAddress.address === '::') ? 'localhost' : serverAddress.address;
});
routes/upload_collection.js
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const router = express.Router();
const uploadCollection = require('../controllers/controller_upload_collection');
const receivedDir = path.join(__dirname, '..', 'cerambyx_data', 'received');
const onlySegmentedDir = path.join(__dirname, '..', 'cerambyx_data', 'only_segmented');
// Configuración de Multer para subida de archivos
const storage = multer.diskStorage({
destination: async function (req, file, cb) {
try {
const identifier = req.body.identifier;
const identifierDir = path.join(receivedDir, identifier); // Ruta completa
fs.mkdirSync(receivedDir, { recursive: true })
fs.mkdirSync(onlySegmentedDir, { recursive: true })
fs.mkdirSync(identifierDir, { recursive: true })
// Llamar al callback de Multer con la ruta completa
cb(null, identifierDir);
} catch (error) {
console.error('Error al verificar o crear la carpeta de destino:', error);
cb(error); // Llamar al callback con el error
}
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const upload = multer({
storage: storage,
limits: { fileSize: 30 * 1024 * 1024 }, // 30MB por archivo
fileFilter: function (req, file, cb) {
// Aquí puedes agregar lógica de filtrado si es necesario
cb(null, true);
}
});
// Ruta para subir fotos
router.post('/', upload.array('photos', 12), uploadCollection);
module.exports = router;
controllers/controller_upload_collection.js
const fs = require('fs');
const path = require('path');
//const pool = require('../db'); // Ajusta la ruta según la ubicación real de tu archivo db.js
const { writeDataToCSV } = require('../csv_writer'); // Importar el módulo csvWriter
const uploadCollection = async (req, res, next) => {
try {
// Verificar si se enviaron archivos
if (!req.files || req.files.length === 0) {
const error = new Error('No se han enviado archivos.');
error.status = 400;
return next(error); // Detener la ejecución aquí
}
// Verificar si se proporcionaron todos los parámetros de la solicitud
const { identifier, average_latitude, average_longitude } = req.body;
if (!identifier || !average_latitude || !average_longitude) {
const error = new Error('Faltan parámetros en la solicitud.');
error.status = 400;
return next(error); // Detener la ejecución aquí
}
// Directorio donde se copiarán las fotos
const onlySegmentedDir = path.join(__dirname, '..', 'cerambyx_data', 'only_segmented');
// Copiar las fotos al directorio
const copiedPhotos = [];
for (const photo of req.files) {
if (photo.originalname.includes('RD_SG')) {
const targetPath = path.join(onlySegmentedDir, photo.originalname);
try {
await fs.promises.copyFile(photo.path, targetPath);
copiedPhotos.push(photo.originalname);
console.log(`Archivo ${photo.originalname} copiado`);
} catch (error) {
console.error(`Error al copiar el archivo ${photo.originalname}:`, error);
return next(error); // Detener la ejecución aquí
}
}
}
// Verificar si se copiaron todas las fotos
if (copiedPhotos.length === 0) {
const error = new Error('No se han podido copiar las fotos segmentadas que pudieran existir a la carpeta only_segmented.');
error.status = 500;
return next(error); // Detener la ejecución aquí
}
// Insertamos en un fichero csv los datos de la subida
try {
// Obtener la fecha actual
const currentDate = new Date().toISOString();
// Crear el objeto de datos para escribir en el archivo CSV
const dataToWrite = {
date: currentDate,
identifier: identifier,
average_latitude: average_latitude,
average_longitude: average_longitude,
filenames: JSON.stringify(copiedPhotos)
};
await writeDataToCSV(dataToWrite);
res.status(200).json({ message: 'Colección subida correctamente' });
} catch (error) {
return next(error); // Detener la ejecución aquí
}
} catch (error) {
return next(error); // Detener la ejecución aquí
}
};
module.exports = uploadCollection;
I only have one route to POST.