My express server is not responding to any of the route requests, whatever I do no luck.
following are the routes I am trying to access:
http://localhost:3000/api/files
http://localhost:3000/files/<:uuid>
http://localhost:3000/api/files/send
Terminal output:
Response via insomia:
Following are the files of the project
server.js
const express = require('express');
const app = express();
const path = require('path');
app.use(express.static('public'));
app.use(express.json);
const PORT = process.env.PORT||3000;
const connectDB = require('./config/db');
connectDB();
app.set('views', path.join(__dirname, '/views'));
app.set('view engine', 'ejs');
app.use('/api/files', require('./routes/files'));
app.use('/files', require('./routes/show'));
app.use('/files/download', require('./routes/download'));
console.log("Server");
app.listen(PORT, () =>{
console.log(`Listening on port ${PORT}`);
});
routes/files.js
const router = require('express').Router();
const multer = require('multer');
const path = require('path');
const File = require('../models/file');
const {v4 : uuid4} = require('uuid');
const sendMail = require('../services/email');
require('dotenv').config();
let storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, 'uploads/'),
filename: (req, file, cb) => {
const uniqueName = `${Date.now()}-${Math.round(Math.random() * 1E9)}${path.extname(file.originalname)}`;
cb(null, uniqueName)
},
});
let upload = multer({
storage:storage,
limit: { fileSize: 100000*200},
}).single('myfile');
router.post('/', (req, res) => {
console.log("Reached here");
console.log(req);
// store locally
upload(req, res, async (err) => {
// check for valid req
if(!req.file){
return res.json({
error: "Error processing file!"
});
}
if(err){ return res.status(500).send({error: err.message})}
// store in db
const file = File({
filename: req.file.filename,
uuid: uuid4(),
path: req.file.path,
size: req.file.size,
});
const response = await file.save();
return res.json({file: `${process.env['APP_BASE_URL']}/files/${response.uuid}`})
});
//return link
});
router.post('/send', async (req, res) => {
console.log(req.body);
const {uuid, emailTo, emailFrom} = req.body;
if(!uuid || !emailTo || !emailFrom){ return res.status(422).send({error: 'All files are required.'});}
const file = await File.findOne({uuid: uuid});
if(file.sender){
return res.status(422).send({error: 'Email already sent.'});
}
file.sender = emailFrom;
file.receiver = emailTo;
const response = await file.save();
sendMail({
from: emailFrom,
to: emailTo,
subject: "shareMe File Sharing",
text: `${emailFrom} shared a file with you`,
html: require('../service/template')({
emailFrom: emailFrom,
downloadLink: `${process.env['APP_BASE_URL']}/files/${file.uuid}`,
size: parseInt(file.size/1000)+'KB',
expires: '24 hours'
})
});
return res.send({success: true});
});
module.exports=router;
routes/show.js
const router = require('express').Router();
const File = require('../models/file');
router.get('/:uuid', async (req, res) => {
try{
const file = await File.findOne({
uuid: req.params.uuid
});
if(!file){
return res.render('download', {error: 'File not fetched.'});
}
console.log(`${process.env['APP_BASE_URL']}/files/download/${file.uuid}`);
return res.render('download', {
uuid: file.uuid,
fileName: file.filename,
size: file.size,
downloadLink: `${process.env['APP_BASE_URL']}/files/download/${file.uuid}`,
});
}catch(err){
return res.render('download', {error: 'Something seems to be upset :('});
}
});
module.exports = router;
routes/download.js
const router = require('express').Router();
const File = require('../models/file');
router.get('/:uuid', async (req, res) => {
// Extract link and get file from storage send download stream
const file = await File.findOne({ uuid: req.params.uuid });
// Link expired
if(!file) {
return res.render('download', { error: 'Link has been expired.'});
}
const response = await file.save();
const filePath = `${__dirname}/../${file.path}`;
res.download(filePath);
});
module.exports = router;
Related
//Error
GET http://localhost:8080/Uploads/2022-01-05T15-45-33.363Z-portfolio.png net::ERR_BLOCKED_BY_RESPONSE.NotSameOrigin 200
Files and other fields were saved database but I could not fetch the images server while I can reach other fields.
//Server
*Client APIs*
const create = async (credentials, restaurant) => {
try {
let response = await fetch(config.ServerURI + "/restaurants", {
method: "POST",
headers: {
"Authorization": "Bearer " + credentials.t,
},
body: restaurant,
});
return await response.json();
} catch (error) {
console.log(error);
}
};
const list = async (signal) => {
try {
let response = await fetch(config.ServerURI + "/restaurants", {
method: "GET",
signal: signal,
});
return await response.json();
} catch (error) {
console.log(error);
}
};
//Multer middleware
const multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './Uploads');
},
filename: function (req, file, cb) {
cb(
null,
`${new Date().toISOString().replace(/:/g, '-')}-${
file.originalname
}`
);
},
});
const filefilter = (req, file, cb) => {
if (
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg'
) {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({ storage: storage, fileFilter: filefilter });
//Server
const create = async (req, res) => {
const user = req.auth._id;
let filesArray = [];
req.files?.forEach((element) => {
const file = {
fileName: element.originalname,
filePath: element.path,
fileType: element.mimetype,
fileSize: fileSizeFormatter(element.size, 2),
};
filesArray.push(file);
});
const { name, location, cost, rating } = req.body;
const { restaurantId } = await createRestaurant(
name,
location,
cost,
rating,
filesArray,
user
);
res.json({ restaurantId });
};
// app.js
require('dotenv').config();
require('express-async-errors');
// const path = require('path');
// extra security packages
const helmet = require('helmet');
const cors = require('cors');
const xss = require('xss-clean');
const cookieParser = require('cookie-parser');
const express = require('express');
// DataBase and Middlewares
const connectDB = require('./db/connect.js');
const {
rateLimiterUsingThirdParty,
} = require('./middlewares/rateLimiter.js');
// Routes
const authRoutes = require('./routes/auth.routes.js');
const userRoutes = require('./routes/user.routes.js');
const restRoutes = require('./routes/restaurant.routes.js');
// error handler
const notFoundMiddleware = require('./middlewares/not-found');
const errorHandlerMiddleware = require('./middlewares/error-handler');
const app = express();
// Middlewares
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
cors({
origin: '*',
})
);
app.set('trust proxy', 1);
app.use(helmet());
app.use(xss());
app.use(cookieParser());
// API-DOCUMENTATION
app.get('/', (req, res) => {
res.send('<h1>Restaurants API</h1>');
});
// routes
app.use('/api/v1/auth', rateLimiterUsingThirdParty, authRoutes);
app.use('/api/v1/users', userRoutes);
app.use('/api/v1/restaurants', restRoutes);
app.use(notFoundMiddleware);
app.use(errorHandlerMiddleware);
const port = process.env.PORT || 5000;
const start = async () => {
try {
connectDB(process.env.MONGO_URI);
app.listen(port, () =>
console.log(`Server is listening on port ${port}...`)
);
} catch (error) {
console.log(error);
}
};
start();
module.exports = app;
Hope you're doing well.
I have a question regarding my Node.js backend app. I am trying to upload an image and a video but I get this error :
"error": "Unexpected field" on postman
Here is my code :
create:(req,res)=>{
console.log("Test1");
console.log("Test1bis");
//const exercise=JSON.parse(req.body.exercise);
//delete exercise._id;
console.log("Test2")
var exerciseB = new Exercise({
...req.body,
image:`${req.protocol}://${req.get('host')}/images/exercise/${req.file.filename1}`,
video:`${req.protocol}://${req.get('host')}/videos/exercise/${req.file.filename2}`
})
console.log("Test3")
exerciseB.save((err,exercise)=>{
if(err){
console.log("C'est le 2eme err");
return res.status(500).json({
status:500,
message:err.message
})
}
console.log("Ca arrive jusqu'au 200");
return res.status(201).json({
status:200,
message:"Exercise Created Successfully !"
})
})
}
And this is the multer file I am using to generate the image in a separate file ( I am using a similar multer for the video) :
const multer=require('multer');
const MIME_TYPES={
'image/jpg':'jpg',
'image/jpeg':'jpg',
'image/png':'png'
}
const storage=multer.diskStorage({
destination:(req,file,callback)=>{
callback(null,'public/images/exercise');
},
filename1:(req,file,callback)=>{
var name=Math.floor(Math.random()*Math.floor(123456789)).toString();
name+=Math.floor(Math.random()*Math.floor(123456789)).toString();
name+=Math.floor(Math.random()*Math.floor(123456789)).toString();
name+=Math.floor(Math.random()*Math.floor(123456789)).toString();
name+=Date.now()+".";
const extension=MIME_TYPES[file.mimetype];
name+=extension;
callback(null,name)
}
})
module.exports=multer({storage}).single('image');
And here is my postman screenshot :
This is my other multer file for the video :
const multer=require('multer');
const MIME_TYPES={
'video/mp4':'mp4',
'video/mpeg':'mpeg',
'video/ogg':'ogv',
'video/mp2t':'ts',
'video//webm':'webm',
}
const storage=multer.diskStorage({
destination:(req,file,callback)=>{
callback(null,'public/videos/exercise');
},
filename2:(req,file,callback)=>{
var name=Math.floor(Math.random()*Math.floor(123456789)).toString();
name+=Math.floor(Math.random()*Math.floor(123456789)).toString();
name+=Math.floor(Math.random()*Math.floor(123456789)).toString();
name+=Math.floor(Math.random()*Math.floor(123456789)).toString();
name+=Date.now()+".";
const extension=MIME_TYPES[file.mimetype];
name+=extension;
callback(null,name)
}
})
module.exports=multer({storage}).single('video');
And this is my routes file :
var express = require('express');
var router = express.Router();
var exerciseController = require('../controllers/exerciseController');
const multerImage=require('../middlewares/multer-image');
const multerVideo=require('../middlewares/multer-video');
/* GET home page. */
router.get('/show', exerciseController.show);
router.post('/create',multerImage, multerVideo, exerciseController.create);
router.put('/update/:id',multerImage, exerciseController.update);
module.exports = router;
I think I can't proceed the way I do in the routes file in the second router call.
Hope you can help me ! Thank you for trying too :)
remove this line
module.exports=multer({storage}).single('image');
and set this line because image is not your name filename1/filename2 your image name
module.exports=multer({storage}).single('filename1');
This is running code but make sure you already created dir public/uploads, you edit your upload location and upload multiple file
const express = require('express');
const bodyParser = require('body-parser');
const multer = require('multer');
const app = express();
app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }))
app.use(bodyParser.json({ limit: '10mb', extended: true }))
app.use(express.static('public/uploads'))
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public/uploads")
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
})
app.post('/', (req, res) => {
const upload = multer({ storage: storage }).single('image_url');
upload(req, res, function (err) {
if (err) {
console.log(err)
return
}
var exerciseB = new Exercise({
...req.body,
image: `${req.protocol}://${req.get('host')}/images/exercise/${req.file.originalname}`,
video: `${req.protocol}://${req.get('host')}/videos/exercise/${req.file.originalname}`
})
exerciseB.save((err, exercise) => {
if (err) {
console.log("C'est le 2eme err");
return res.status(500).json({
status: 500,
message: err.message
})
}
console.log("Ca arrive jusqu'au 200");
return res.status(201).json({
status: 200,
message: "Exercise Created Successfully !"
})
})
})
})
app.listen(9001, () => {
console.log(`listening on port ${9001}`)
});
i have a problem if you can help,
i've deployed my app on heroku and it's working properly on localhost when i upload product picture when launching on localhost everything is working and the picture is added to my public folder and the url is passed to my Product image url field, but when doing the same on heroku deployed app it shows: "ENOENT: no such file or directory, open 'public/obNHUnF85G2kHtApYvix5D-1200-80-1617359184714.png"
thx in advance
Here is my app.js
const express = require('express')
const morgan = require('morgan')
const mongoose = require('mongoose')
const jwt = require('jsonwebtoken');
var cors = require('cors')
const errorHandler = require('./middleware/error')
const app = express()
var corsOptions = {
origin: "*",
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.use(cors(corsOptions))
app.use(express.static('public'))
app.use(express.json())
app.use(morgan('tiny'))
require('dotenv/config')
const productRouter = require('./Routes/ProductRouter')
const categoryRouter = require('./Routes/CategoryRouter');
const authRoute = require('./Routes/auth');
const userRoute = require('./Routes/user');
const OrderRouter = require('./Routes/OrderRouter');
const imagesRouter = require('./Routes/addImagesRoute');
const { static } = require('express');
const apiUrl = process.env.API_URL
const port = process.env.PORT;
mongoose
.connect(process.env.CONNECTION_STRING, {
useUnifiedTopology: true,
useNewUrlParser: true
})
.then(() => {
console.log('connected successfully')
})
.catch(err => {
console.log(err)
})
app.use(`${apiUrl}/products`, productRouter)
app.use(`${apiUrl}/categories`, categoryRouter)
app.use(`${apiUrl}/auth`, authRoute)
app.use(`${apiUrl}/users`, userRoute)
app.use(`${apiUrl}/orders`, OrderRouter)
app.use(`${apiUrl}/images`, imagesRouter)
app.use(errorHandler);
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
My Uploading Router
const express = require('express')
const { uploadImage, uploadGalleryImages } = require('../controllers/uploadController')
const { authorize, protect } = require('../middleware/auth')
const uploadRouter = express.Router()
const multer = require('multer')
const path = require('path')
const FILE_TYPE_MAP = {
'image/png': 'png',
'image/jpeg': 'jpeg',
'image/jpg': 'jpg'
}
const storage = multer.diskStorage({
destination: function(req, file, cb) {
const isValid = FILE_TYPE_MAP[file.mimetype]
let uploadError = new Error('invalid image type')
if (isValid) {
uploadError = null
}
cb(uploadError, 'public/')
},
filename: function(req, file, cb) {
const fileName = file.originalname.split(' ').join('-')
const extension = FILE_TYPE_MAP[file.mimetype]
cb(null, `${fileName.split('.', 1)}-${Date.now()}${path.extname(file.originalname)}`)
}
})
const uploadOptions = multer({ storage: storage })
uploadRouter.use(protect)
uploadRouter.use(authorize('publisher', 'admin'))
uploadRouter.post(
'/:productId/image',
uploadOptions.single('image'),
uploadImage
);
uploadRouter.put('/:productId/images', uploadOptions.array('images', 8), uploadGalleryImages);
module.exports = uploadRouter;
Adding url and hash function
const file = req.file
if (!file) return res.status(400).send('No image in the request')
const fileName = file.filename
const basePath = `${req.protocol}://${req.get('host')}/`
try {
const product = await Product.findByIdAndUpdate(
req.params.productId, {
imageUrl: `${basePath}${file.filename.split('.', 1)}${path.extname(
file.originalname
)}`
}, { new: true }
);
await product.save();
const url = product.imageUrl;
const hash = await handler(url.toString());
const hashString = JSON.parse(hash).blurHash;
await Product.findByIdAndUpdate(req.params.productId, {
imageHash: hashString
}, { new: true })
product.save()
res.send(product)
} catch (error) {
return next(new ErrorResponse(`an error occured : ${error}`, 400))
}
})```
when i upload on localhost [Local host request and result][1]
when i upload on heroku server [Heroku][2]
[1]: https://i.stack.imgur.com/Fp8OK.png
[2]: https://i.stack.imgur.com/oaFuC.png
I want to run some custom validation on .xlsx before upload. I have written the basic validation for now but my upload not working.
const express = require('express');
const app = express();
const multer = require('multer');
const router = express.Router();
const uploadExcel = require('./excelMiddleware');
const multerS = multer();
const upload = multer({
dest:'excel',
fileFilter(res, file, cb){
if(!file.originalname.match(/\.(xls|xlsx)$/)){
return cb(new Error('Please upload a excel file'));
}
cb(undefined, true)
}
}).single('file');
router.post('/upload', multerS.single('file'), uploadExcel, upload, (req, res) => {
upload(req, res, function (err, data) {
if (err) throw err;
})
res.send('<h1>file uploaded</h1>')
})
router.get('*', (req, res) => {
res.send('<h1>Page not found</h1>')
})
app.use(router);
app.listen(8000, ()=> {
console.log('Server stared')
})
excelMiddleware.js
const XLSX = require('xlsx');
const { CONTACT } = require('./column.config');
const _ = require('lodash');
const uploadExcel = (req, res, next) => {
try{
const columnMapper = CONTACT;
const workbook = XLSX.read(req.file.buffer, {type:'buffer'});
const sheetName = workbook.SheetNames;
const excelJson = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName[0]]);
if(!excelJson.length) {
throw Error("Blank sheet");
}
const columnCheck = Object.keys(excelJson[0]);
const isColumnEqual = _.isEqual(columnMapper, columnCheck);
if(!isColumnEqual){
throw Error("Blank sheet");
}
next();
}
catch(e){
console.log(e)
return res.status(400).send({error:e.message});
}
}
module.exports = uploadExcel;
I am trying to create a user profile in express.js and MongoDB. I am using multer for image uploading. Multer middleware always uploads the image before verifying my user data. If user validation is failed, nevertheless image is uploaded. But, I want to upload an image after validating user data. That means, I will check user data in the controller, and if it is valid then I will upload image and store user data to MongoDB. How can I do that? Thanks in advance!
multerConfig.js
exports.multerConfig = (multer) => {
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './uploads/');
},
filename: (req, file, cb) => {
cb(null, 'img-' + new Date().toISOString() + '-' + file.originalname);
}
});
const fileFilter = (req, file, cb) => {
(file.mimetype === 'image/png' || file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg')
? cb(null, true)
: cb(null, false)
};
return multer({
storage: storage,
limits: { fileSize: 1048576 },
fileFilter: fileFilter
});
};
user.js(Routes)
const multer = require('multer');
const express = require('express');
const userController = require('../controllers/user');
const { multerConfig } = require('../utility/multerConfig');
const validateObjectId = require('../middleware/validateObjectId');
const asyncErrorHandler = require('../middleware/asyncErrorHandler');
const router = express.Router();
const upload = multerConfig(multer);
router.post('/', upload.single('image'), asyncErrorHandler(userController.createUser));
module.exports = router;
user.js(Controller)
const { User, validate } = require('../models/user');
const { deleteFile } = require('../utility/fileUtility');
const { failed, success } = require('../utility/utility');
exports.createUser = async (req, res) => {
const { error } = validate(req.body);
if (error) return res.status(400).send({ ...failed, message: error.details[0].message });
const { name, address, mobile, email, password } = req.body;
if (!req.file) return res.status(400).send({ ...failed, message: `you have to upload an image!` });
const isUserExist = await User.find().or([{ mobile }, { email }]);
if (isUserExist.length > 0) return res.status(409).send({ ...failed, message: `${name} is already exists!` });
const image = req.file.path;
const newUser = new User({ name, address, mobile, email, password, image });
const savedUser = await newUser.save();
if (!savedUser) return res.status(500).send({ ...failed, message: `user ${name} is failed to save!` });
res.send({
...success,
data: savedUser,
message: `user ${name} is saved successfully`
});
};
You can use two multer middleware (one for parsing text, one for uploading your file).
Let's say you have a form with a name (text field) and avatar (file field), you can do this:
var express = require('express');
var multer = require('multer');
var app = express();
var upload = multer({ dest: 'uploads/' });
app.post('/profile',
upload.none(), function (req, res, next) {
// validate `req.body.name` here
// and call next(err) if it fails
next();
},
upload.single('avatar'), function (req, res, next) {
// file is now uploaded, save the location to the database
res.end('done!');
});
app.listen(9000);