increase express post body limit to proxied api
up vote
0
down vote
favorite
I have a seperate frontend and backend, where all requests to http://frontend.com/api are proxied to the backend. However we allow image uploads to be 10mb max, which gets limited by the 1mb internal limit of express on all request bodies.
I have the following config:
const express = require('express');
const consola = require('consola');
const { Nuxt, Builder } = require('nuxt');
const helmet = require('helmet');
// Express
const app = express();
const host = process.env.HOST || '127.0.0.1';
const port = process.env.PORT || 8080;
app.set('port', port);
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js');
config.dev = !(process.env.NODE_ENV === 'production');
async function start() {
// Init Nuxt.js
const nuxt = new Nuxt(config);
if (config.dev) {
const builder = new Builder(nuxt);
await builder.build();
}
// NOTE: Only in production mode
if (!config.dev) {
// Helmet default security + Referrer + Features
app.use(helmet());
}
// Proxy /api to proper backend
app.use('/api', proxy(process.env.API_ENDPOINT || 'http://localhost:3000'));
// Give nuxt middleware to express
app.use(nuxt.render);
// Listen the server
app.listen(port, host);
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true,
});
}
start();
I have tried adding body-parser, until I found out this only works for non multipart/form type of requests. Considering that this isn't an express backend, but only used to serve SSR (with nuxt), I have no idea how to get this to work with something like multer or busboy.
Can this be done without having to setup nginx as a reverse proxy?
node.js express nuxt.js
|
show 1 more comment
up vote
0
down vote
favorite
I have a seperate frontend and backend, where all requests to http://frontend.com/api are proxied to the backend. However we allow image uploads to be 10mb max, which gets limited by the 1mb internal limit of express on all request bodies.
I have the following config:
const express = require('express');
const consola = require('consola');
const { Nuxt, Builder } = require('nuxt');
const helmet = require('helmet');
// Express
const app = express();
const host = process.env.HOST || '127.0.0.1';
const port = process.env.PORT || 8080;
app.set('port', port);
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js');
config.dev = !(process.env.NODE_ENV === 'production');
async function start() {
// Init Nuxt.js
const nuxt = new Nuxt(config);
if (config.dev) {
const builder = new Builder(nuxt);
await builder.build();
}
// NOTE: Only in production mode
if (!config.dev) {
// Helmet default security + Referrer + Features
app.use(helmet());
}
// Proxy /api to proper backend
app.use('/api', proxy(process.env.API_ENDPOINT || 'http://localhost:3000'));
// Give nuxt middleware to express
app.use(nuxt.render);
// Listen the server
app.listen(port, host);
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true,
});
}
start();
I have tried adding body-parser, until I found out this only works for non multipart/form type of requests. Considering that this isn't an express backend, but only used to serve SSR (with nuxt), I have no idea how to get this to work with something like multer or busboy.
Can this be done without having to setup nginx as a reverse proxy?
node.js express nuxt.js
I've used what sounds like a similar setup to you and use multer and set my upload limits with it. I can post my code in an answer if you'd like to see it. I haven't tried it with files over 1mb so can't vouch for that but it may work. Let me know.
– Andrew1325
Nov 8 at 9:13
Would be nice to see an example, wonder if you hardcoded the endpoints or only used it as a proxy for parsing the body.
– user1213904
Nov 8 at 13:03
1
"which gets limited by the 1mb internal limit of express on all request bodies". There is no such thing, though. Perhaps one of the other middleware that you're using (helmet,proxy) are responsible for imposing a limit. The stack trace of the error you're getting might provide some insight.
– robertklep
Nov 8 at 21:08
@robertklep You were right, I could have sworn that I read that express imposes a limit somewhere, and come to think of it, being a default that is this hard to change wouldn't be very lucrative. The only express limit I could find is for json bodies: expressjs.com/en/api.html#express.json. In the end "express-force-https" sets a hard limit of 1mb for all proxied requests. Changing this fixed the issue. If you could make an answer of it, I would gladly accept it :).
– user1213904
Nov 8 at 21:39
@user1213904express-force-httpsdoesn't set a limit either :)
– robertklep
Nov 9 at 6:19
|
show 1 more comment
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have a seperate frontend and backend, where all requests to http://frontend.com/api are proxied to the backend. However we allow image uploads to be 10mb max, which gets limited by the 1mb internal limit of express on all request bodies.
I have the following config:
const express = require('express');
const consola = require('consola');
const { Nuxt, Builder } = require('nuxt');
const helmet = require('helmet');
// Express
const app = express();
const host = process.env.HOST || '127.0.0.1';
const port = process.env.PORT || 8080;
app.set('port', port);
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js');
config.dev = !(process.env.NODE_ENV === 'production');
async function start() {
// Init Nuxt.js
const nuxt = new Nuxt(config);
if (config.dev) {
const builder = new Builder(nuxt);
await builder.build();
}
// NOTE: Only in production mode
if (!config.dev) {
// Helmet default security + Referrer + Features
app.use(helmet());
}
// Proxy /api to proper backend
app.use('/api', proxy(process.env.API_ENDPOINT || 'http://localhost:3000'));
// Give nuxt middleware to express
app.use(nuxt.render);
// Listen the server
app.listen(port, host);
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true,
});
}
start();
I have tried adding body-parser, until I found out this only works for non multipart/form type of requests. Considering that this isn't an express backend, but only used to serve SSR (with nuxt), I have no idea how to get this to work with something like multer or busboy.
Can this be done without having to setup nginx as a reverse proxy?
node.js express nuxt.js
I have a seperate frontend and backend, where all requests to http://frontend.com/api are proxied to the backend. However we allow image uploads to be 10mb max, which gets limited by the 1mb internal limit of express on all request bodies.
I have the following config:
const express = require('express');
const consola = require('consola');
const { Nuxt, Builder } = require('nuxt');
const helmet = require('helmet');
// Express
const app = express();
const host = process.env.HOST || '127.0.0.1';
const port = process.env.PORT || 8080;
app.set('port', port);
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js');
config.dev = !(process.env.NODE_ENV === 'production');
async function start() {
// Init Nuxt.js
const nuxt = new Nuxt(config);
if (config.dev) {
const builder = new Builder(nuxt);
await builder.build();
}
// NOTE: Only in production mode
if (!config.dev) {
// Helmet default security + Referrer + Features
app.use(helmet());
}
// Proxy /api to proper backend
app.use('/api', proxy(process.env.API_ENDPOINT || 'http://localhost:3000'));
// Give nuxt middleware to express
app.use(nuxt.render);
// Listen the server
app.listen(port, host);
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true,
});
}
start();
I have tried adding body-parser, until I found out this only works for non multipart/form type of requests. Considering that this isn't an express backend, but only used to serve SSR (with nuxt), I have no idea how to get this to work with something like multer or busboy.
Can this be done without having to setup nginx as a reverse proxy?
node.js express nuxt.js
node.js express nuxt.js
asked Nov 7 at 18:48
user1213904
701826
701826
I've used what sounds like a similar setup to you and use multer and set my upload limits with it. I can post my code in an answer if you'd like to see it. I haven't tried it with files over 1mb so can't vouch for that but it may work. Let me know.
– Andrew1325
Nov 8 at 9:13
Would be nice to see an example, wonder if you hardcoded the endpoints or only used it as a proxy for parsing the body.
– user1213904
Nov 8 at 13:03
1
"which gets limited by the 1mb internal limit of express on all request bodies". There is no such thing, though. Perhaps one of the other middleware that you're using (helmet,proxy) are responsible for imposing a limit. The stack trace of the error you're getting might provide some insight.
– robertklep
Nov 8 at 21:08
@robertklep You were right, I could have sworn that I read that express imposes a limit somewhere, and come to think of it, being a default that is this hard to change wouldn't be very lucrative. The only express limit I could find is for json bodies: expressjs.com/en/api.html#express.json. In the end "express-force-https" sets a hard limit of 1mb for all proxied requests. Changing this fixed the issue. If you could make an answer of it, I would gladly accept it :).
– user1213904
Nov 8 at 21:39
@user1213904express-force-httpsdoesn't set a limit either :)
– robertklep
Nov 9 at 6:19
|
show 1 more comment
I've used what sounds like a similar setup to you and use multer and set my upload limits with it. I can post my code in an answer if you'd like to see it. I haven't tried it with files over 1mb so can't vouch for that but it may work. Let me know.
– Andrew1325
Nov 8 at 9:13
Would be nice to see an example, wonder if you hardcoded the endpoints or only used it as a proxy for parsing the body.
– user1213904
Nov 8 at 13:03
1
"which gets limited by the 1mb internal limit of express on all request bodies". There is no such thing, though. Perhaps one of the other middleware that you're using (helmet,proxy) are responsible for imposing a limit. The stack trace of the error you're getting might provide some insight.
– robertklep
Nov 8 at 21:08
@robertklep You were right, I could have sworn that I read that express imposes a limit somewhere, and come to think of it, being a default that is this hard to change wouldn't be very lucrative. The only express limit I could find is for json bodies: expressjs.com/en/api.html#express.json. In the end "express-force-https" sets a hard limit of 1mb for all proxied requests. Changing this fixed the issue. If you could make an answer of it, I would gladly accept it :).
– user1213904
Nov 8 at 21:39
@user1213904express-force-httpsdoesn't set a limit either :)
– robertklep
Nov 9 at 6:19
I've used what sounds like a similar setup to you and use multer and set my upload limits with it. I can post my code in an answer if you'd like to see it. I haven't tried it with files over 1mb so can't vouch for that but it may work. Let me know.
– Andrew1325
Nov 8 at 9:13
I've used what sounds like a similar setup to you and use multer and set my upload limits with it. I can post my code in an answer if you'd like to see it. I haven't tried it with files over 1mb so can't vouch for that but it may work. Let me know.
– Andrew1325
Nov 8 at 9:13
Would be nice to see an example, wonder if you hardcoded the endpoints or only used it as a proxy for parsing the body.
– user1213904
Nov 8 at 13:03
Would be nice to see an example, wonder if you hardcoded the endpoints or only used it as a proxy for parsing the body.
– user1213904
Nov 8 at 13:03
1
1
"which gets limited by the 1mb internal limit of express on all request bodies". There is no such thing, though. Perhaps one of the other middleware that you're using (
helmet, proxy) are responsible for imposing a limit. The stack trace of the error you're getting might provide some insight.– robertklep
Nov 8 at 21:08
"which gets limited by the 1mb internal limit of express on all request bodies". There is no such thing, though. Perhaps one of the other middleware that you're using (
helmet, proxy) are responsible for imposing a limit. The stack trace of the error you're getting might provide some insight.– robertklep
Nov 8 at 21:08
@robertklep You were right, I could have sworn that I read that express imposes a limit somewhere, and come to think of it, being a default that is this hard to change wouldn't be very lucrative. The only express limit I could find is for json bodies: expressjs.com/en/api.html#express.json. In the end "express-force-https" sets a hard limit of 1mb for all proxied requests. Changing this fixed the issue. If you could make an answer of it, I would gladly accept it :).
– user1213904
Nov 8 at 21:39
@robertklep You were right, I could have sworn that I read that express imposes a limit somewhere, and come to think of it, being a default that is this hard to change wouldn't be very lucrative. The only express limit I could find is for json bodies: expressjs.com/en/api.html#express.json. In the end "express-force-https" sets a hard limit of 1mb for all proxied requests. Changing this fixed the issue. If you could make an answer of it, I would gladly accept it :).
– user1213904
Nov 8 at 21:39
@user1213904
express-force-https doesn't set a limit either :)– robertklep
Nov 9 at 6:19
@user1213904
express-force-https doesn't set a limit either :)– robertklep
Nov 9 at 6:19
|
show 1 more comment
2 Answers
2
active
oldest
votes
up vote
0
down vote
accepted
Express itself doesn't impose any limits on body size, because it doesn't process the request body at all.
However, some middleware do impose a limit, like body-parser and express-http-proxy, which is what you're using.
To increase the limit to 10MB:
app.use('/api', proxy(process.env.API_ENDPOINT || 'http://localhost:3000', {
limit: '10mb'
));
add a comment |
up vote
0
down vote
The way mine works is I define my api base url in a config file which I reference in an api/init.js file. This file is added to plugins in nuxt.config.js. This is that file:
import axios from 'axios'
import {baseURL} from '~/config'
import cookies from 'js-cookie'
import {setAuthToken, resetAuthToken} from '~/utils/auth'
import { setUser, setCart } from '../utils/auth'
axios.defaults.baseURL = baseURL
const token = cookies.get('x-access-token')
const currentUser = cookies.get('userDetails')
const currentCart = cookies.get('userCart')
if (token) {
setAuthToken(token)
setUser(currentUser)
setCart(currentCart)
} else {
resetAuthToken()
}
The backend runs on it's own server which I launch with node index.js and it is the base url that my init.js looks for. The backend index.js looks like this:
const mysql = require('mysql')
const express = require('express')
const bodyParser = require('body-parser')
const config = require('./config')
const jwt = require('jsonwebtoken')
const bcrypt = require('bcrypt')
const multer = require('multer')
const auth = require('./auth')
const files = require('./files')
const create = require('./create')
const get = require('./get')
const delet = require('./delet')
const blogFiles = require('./blogFiles')
const db = mysql.createConnection(config.db)
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS')
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, x-access-token, userDetails, userCart')
if (req.method === 'OPTIONS') {
res.sendStatus(200)
}
else {
next()
}
})
app.use((err, req, res, next) => {
if (err.code === 'LIMIT_FILE_TYPES') {
res.status(422).json({ error: 'Only images are allowed'})
return
}
if (err.code === 'LIMIT_FILE_SIZE') {
res.status(422).json({ error: `Too Large. Max filesize is ${MAX_SIZE/1000}kb` })
return
}
})
app.use('/auth', auth({db, express, bcrypt, jwt, jwtToken: config.jwtToken}))
app.use('/files', files({db, express, multer}))
app.use('/blogFiles', blogFiles({db, express, multer}))
app.use('/create', create({db, express}))
app.use('/get', get({db, express}))
app.use('/delet', delet({db, express}))
app.get('/test', (req, res) => {
db.query('select 1+1', (error, results) => {
if (error) {
return res.status(500).json({type: 'error', error})
}
res.json({type: 'success', message: 'Test OK', results})
})
})
app.listen(config.port)
console.log('App is running on port ' + config.port)
The files.js handles file uploads and as you can see index.js requires that. It is in there that I use multer to handle the upload limit and such. This is file.js
module.exports = ({db, express, multer }) => {
const routes = express.Router()
const fileFilter = function(req, file, cb) {
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!allowedTypes.includes(file.mimetype)) {
const error = new Error('Wrong file type')
error.code = 'LIMIT_FILE_TYPES'
return cb(error, false)
}
cb(null, true)
}
const MAX_SIZE = 250000
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../frontend/assets/images')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer ({
storage: storage,
fileFilter,
limits: {
fileSize: MAX_SIZE
},
})
routes.post('/upload', upload.single('file'), (req, res) => {
res.json({ file: req.file })
})
return routes
}
As you can see I set the MAX_SIZE for my file uploads here so guess you can set any limit and as multer is handling it, it will over ride any limits set by express.
Thanks for the clear answer, however my backend is in Rails unfortunately. I didn't account for the proxy which passes all requests to frontend/api would enforce a hard limit of 1mb. Altogether, your answer is a clear future reference.
– user1213904
Nov 8 at 21:49
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
Express itself doesn't impose any limits on body size, because it doesn't process the request body at all.
However, some middleware do impose a limit, like body-parser and express-http-proxy, which is what you're using.
To increase the limit to 10MB:
app.use('/api', proxy(process.env.API_ENDPOINT || 'http://localhost:3000', {
limit: '10mb'
));
add a comment |
up vote
0
down vote
accepted
Express itself doesn't impose any limits on body size, because it doesn't process the request body at all.
However, some middleware do impose a limit, like body-parser and express-http-proxy, which is what you're using.
To increase the limit to 10MB:
app.use('/api', proxy(process.env.API_ENDPOINT || 'http://localhost:3000', {
limit: '10mb'
));
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
Express itself doesn't impose any limits on body size, because it doesn't process the request body at all.
However, some middleware do impose a limit, like body-parser and express-http-proxy, which is what you're using.
To increase the limit to 10MB:
app.use('/api', proxy(process.env.API_ENDPOINT || 'http://localhost:3000', {
limit: '10mb'
));
Express itself doesn't impose any limits on body size, because it doesn't process the request body at all.
However, some middleware do impose a limit, like body-parser and express-http-proxy, which is what you're using.
To increase the limit to 10MB:
app.use('/api', proxy(process.env.API_ENDPOINT || 'http://localhost:3000', {
limit: '10mb'
));
answered Nov 9 at 11:59
robertklep
132k17227238
132k17227238
add a comment |
add a comment |
up vote
0
down vote
The way mine works is I define my api base url in a config file which I reference in an api/init.js file. This file is added to plugins in nuxt.config.js. This is that file:
import axios from 'axios'
import {baseURL} from '~/config'
import cookies from 'js-cookie'
import {setAuthToken, resetAuthToken} from '~/utils/auth'
import { setUser, setCart } from '../utils/auth'
axios.defaults.baseURL = baseURL
const token = cookies.get('x-access-token')
const currentUser = cookies.get('userDetails')
const currentCart = cookies.get('userCart')
if (token) {
setAuthToken(token)
setUser(currentUser)
setCart(currentCart)
} else {
resetAuthToken()
}
The backend runs on it's own server which I launch with node index.js and it is the base url that my init.js looks for. The backend index.js looks like this:
const mysql = require('mysql')
const express = require('express')
const bodyParser = require('body-parser')
const config = require('./config')
const jwt = require('jsonwebtoken')
const bcrypt = require('bcrypt')
const multer = require('multer')
const auth = require('./auth')
const files = require('./files')
const create = require('./create')
const get = require('./get')
const delet = require('./delet')
const blogFiles = require('./blogFiles')
const db = mysql.createConnection(config.db)
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS')
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, x-access-token, userDetails, userCart')
if (req.method === 'OPTIONS') {
res.sendStatus(200)
}
else {
next()
}
})
app.use((err, req, res, next) => {
if (err.code === 'LIMIT_FILE_TYPES') {
res.status(422).json({ error: 'Only images are allowed'})
return
}
if (err.code === 'LIMIT_FILE_SIZE') {
res.status(422).json({ error: `Too Large. Max filesize is ${MAX_SIZE/1000}kb` })
return
}
})
app.use('/auth', auth({db, express, bcrypt, jwt, jwtToken: config.jwtToken}))
app.use('/files', files({db, express, multer}))
app.use('/blogFiles', blogFiles({db, express, multer}))
app.use('/create', create({db, express}))
app.use('/get', get({db, express}))
app.use('/delet', delet({db, express}))
app.get('/test', (req, res) => {
db.query('select 1+1', (error, results) => {
if (error) {
return res.status(500).json({type: 'error', error})
}
res.json({type: 'success', message: 'Test OK', results})
})
})
app.listen(config.port)
console.log('App is running on port ' + config.port)
The files.js handles file uploads and as you can see index.js requires that. It is in there that I use multer to handle the upload limit and such. This is file.js
module.exports = ({db, express, multer }) => {
const routes = express.Router()
const fileFilter = function(req, file, cb) {
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!allowedTypes.includes(file.mimetype)) {
const error = new Error('Wrong file type')
error.code = 'LIMIT_FILE_TYPES'
return cb(error, false)
}
cb(null, true)
}
const MAX_SIZE = 250000
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../frontend/assets/images')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer ({
storage: storage,
fileFilter,
limits: {
fileSize: MAX_SIZE
},
})
routes.post('/upload', upload.single('file'), (req, res) => {
res.json({ file: req.file })
})
return routes
}
As you can see I set the MAX_SIZE for my file uploads here so guess you can set any limit and as multer is handling it, it will over ride any limits set by express.
Thanks for the clear answer, however my backend is in Rails unfortunately. I didn't account for the proxy which passes all requests to frontend/api would enforce a hard limit of 1mb. Altogether, your answer is a clear future reference.
– user1213904
Nov 8 at 21:49
add a comment |
up vote
0
down vote
The way mine works is I define my api base url in a config file which I reference in an api/init.js file. This file is added to plugins in nuxt.config.js. This is that file:
import axios from 'axios'
import {baseURL} from '~/config'
import cookies from 'js-cookie'
import {setAuthToken, resetAuthToken} from '~/utils/auth'
import { setUser, setCart } from '../utils/auth'
axios.defaults.baseURL = baseURL
const token = cookies.get('x-access-token')
const currentUser = cookies.get('userDetails')
const currentCart = cookies.get('userCart')
if (token) {
setAuthToken(token)
setUser(currentUser)
setCart(currentCart)
} else {
resetAuthToken()
}
The backend runs on it's own server which I launch with node index.js and it is the base url that my init.js looks for. The backend index.js looks like this:
const mysql = require('mysql')
const express = require('express')
const bodyParser = require('body-parser')
const config = require('./config')
const jwt = require('jsonwebtoken')
const bcrypt = require('bcrypt')
const multer = require('multer')
const auth = require('./auth')
const files = require('./files')
const create = require('./create')
const get = require('./get')
const delet = require('./delet')
const blogFiles = require('./blogFiles')
const db = mysql.createConnection(config.db)
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS')
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, x-access-token, userDetails, userCart')
if (req.method === 'OPTIONS') {
res.sendStatus(200)
}
else {
next()
}
})
app.use((err, req, res, next) => {
if (err.code === 'LIMIT_FILE_TYPES') {
res.status(422).json({ error: 'Only images are allowed'})
return
}
if (err.code === 'LIMIT_FILE_SIZE') {
res.status(422).json({ error: `Too Large. Max filesize is ${MAX_SIZE/1000}kb` })
return
}
})
app.use('/auth', auth({db, express, bcrypt, jwt, jwtToken: config.jwtToken}))
app.use('/files', files({db, express, multer}))
app.use('/blogFiles', blogFiles({db, express, multer}))
app.use('/create', create({db, express}))
app.use('/get', get({db, express}))
app.use('/delet', delet({db, express}))
app.get('/test', (req, res) => {
db.query('select 1+1', (error, results) => {
if (error) {
return res.status(500).json({type: 'error', error})
}
res.json({type: 'success', message: 'Test OK', results})
})
})
app.listen(config.port)
console.log('App is running on port ' + config.port)
The files.js handles file uploads and as you can see index.js requires that. It is in there that I use multer to handle the upload limit and such. This is file.js
module.exports = ({db, express, multer }) => {
const routes = express.Router()
const fileFilter = function(req, file, cb) {
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!allowedTypes.includes(file.mimetype)) {
const error = new Error('Wrong file type')
error.code = 'LIMIT_FILE_TYPES'
return cb(error, false)
}
cb(null, true)
}
const MAX_SIZE = 250000
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../frontend/assets/images')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer ({
storage: storage,
fileFilter,
limits: {
fileSize: MAX_SIZE
},
})
routes.post('/upload', upload.single('file'), (req, res) => {
res.json({ file: req.file })
})
return routes
}
As you can see I set the MAX_SIZE for my file uploads here so guess you can set any limit and as multer is handling it, it will over ride any limits set by express.
Thanks for the clear answer, however my backend is in Rails unfortunately. I didn't account for the proxy which passes all requests to frontend/api would enforce a hard limit of 1mb. Altogether, your answer is a clear future reference.
– user1213904
Nov 8 at 21:49
add a comment |
up vote
0
down vote
up vote
0
down vote
The way mine works is I define my api base url in a config file which I reference in an api/init.js file. This file is added to plugins in nuxt.config.js. This is that file:
import axios from 'axios'
import {baseURL} from '~/config'
import cookies from 'js-cookie'
import {setAuthToken, resetAuthToken} from '~/utils/auth'
import { setUser, setCart } from '../utils/auth'
axios.defaults.baseURL = baseURL
const token = cookies.get('x-access-token')
const currentUser = cookies.get('userDetails')
const currentCart = cookies.get('userCart')
if (token) {
setAuthToken(token)
setUser(currentUser)
setCart(currentCart)
} else {
resetAuthToken()
}
The backend runs on it's own server which I launch with node index.js and it is the base url that my init.js looks for. The backend index.js looks like this:
const mysql = require('mysql')
const express = require('express')
const bodyParser = require('body-parser')
const config = require('./config')
const jwt = require('jsonwebtoken')
const bcrypt = require('bcrypt')
const multer = require('multer')
const auth = require('./auth')
const files = require('./files')
const create = require('./create')
const get = require('./get')
const delet = require('./delet')
const blogFiles = require('./blogFiles')
const db = mysql.createConnection(config.db)
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS')
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, x-access-token, userDetails, userCart')
if (req.method === 'OPTIONS') {
res.sendStatus(200)
}
else {
next()
}
})
app.use((err, req, res, next) => {
if (err.code === 'LIMIT_FILE_TYPES') {
res.status(422).json({ error: 'Only images are allowed'})
return
}
if (err.code === 'LIMIT_FILE_SIZE') {
res.status(422).json({ error: `Too Large. Max filesize is ${MAX_SIZE/1000}kb` })
return
}
})
app.use('/auth', auth({db, express, bcrypt, jwt, jwtToken: config.jwtToken}))
app.use('/files', files({db, express, multer}))
app.use('/blogFiles', blogFiles({db, express, multer}))
app.use('/create', create({db, express}))
app.use('/get', get({db, express}))
app.use('/delet', delet({db, express}))
app.get('/test', (req, res) => {
db.query('select 1+1', (error, results) => {
if (error) {
return res.status(500).json({type: 'error', error})
}
res.json({type: 'success', message: 'Test OK', results})
})
})
app.listen(config.port)
console.log('App is running on port ' + config.port)
The files.js handles file uploads and as you can see index.js requires that. It is in there that I use multer to handle the upload limit and such. This is file.js
module.exports = ({db, express, multer }) => {
const routes = express.Router()
const fileFilter = function(req, file, cb) {
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!allowedTypes.includes(file.mimetype)) {
const error = new Error('Wrong file type')
error.code = 'LIMIT_FILE_TYPES'
return cb(error, false)
}
cb(null, true)
}
const MAX_SIZE = 250000
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../frontend/assets/images')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer ({
storage: storage,
fileFilter,
limits: {
fileSize: MAX_SIZE
},
})
routes.post('/upload', upload.single('file'), (req, res) => {
res.json({ file: req.file })
})
return routes
}
As you can see I set the MAX_SIZE for my file uploads here so guess you can set any limit and as multer is handling it, it will over ride any limits set by express.
The way mine works is I define my api base url in a config file which I reference in an api/init.js file. This file is added to plugins in nuxt.config.js. This is that file:
import axios from 'axios'
import {baseURL} from '~/config'
import cookies from 'js-cookie'
import {setAuthToken, resetAuthToken} from '~/utils/auth'
import { setUser, setCart } from '../utils/auth'
axios.defaults.baseURL = baseURL
const token = cookies.get('x-access-token')
const currentUser = cookies.get('userDetails')
const currentCart = cookies.get('userCart')
if (token) {
setAuthToken(token)
setUser(currentUser)
setCart(currentCart)
} else {
resetAuthToken()
}
The backend runs on it's own server which I launch with node index.js and it is the base url that my init.js looks for. The backend index.js looks like this:
const mysql = require('mysql')
const express = require('express')
const bodyParser = require('body-parser')
const config = require('./config')
const jwt = require('jsonwebtoken')
const bcrypt = require('bcrypt')
const multer = require('multer')
const auth = require('./auth')
const files = require('./files')
const create = require('./create')
const get = require('./get')
const delet = require('./delet')
const blogFiles = require('./blogFiles')
const db = mysql.createConnection(config.db)
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS')
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, x-access-token, userDetails, userCart')
if (req.method === 'OPTIONS') {
res.sendStatus(200)
}
else {
next()
}
})
app.use((err, req, res, next) => {
if (err.code === 'LIMIT_FILE_TYPES') {
res.status(422).json({ error: 'Only images are allowed'})
return
}
if (err.code === 'LIMIT_FILE_SIZE') {
res.status(422).json({ error: `Too Large. Max filesize is ${MAX_SIZE/1000}kb` })
return
}
})
app.use('/auth', auth({db, express, bcrypt, jwt, jwtToken: config.jwtToken}))
app.use('/files', files({db, express, multer}))
app.use('/blogFiles', blogFiles({db, express, multer}))
app.use('/create', create({db, express}))
app.use('/get', get({db, express}))
app.use('/delet', delet({db, express}))
app.get('/test', (req, res) => {
db.query('select 1+1', (error, results) => {
if (error) {
return res.status(500).json({type: 'error', error})
}
res.json({type: 'success', message: 'Test OK', results})
})
})
app.listen(config.port)
console.log('App is running on port ' + config.port)
The files.js handles file uploads and as you can see index.js requires that. It is in there that I use multer to handle the upload limit and such. This is file.js
module.exports = ({db, express, multer }) => {
const routes = express.Router()
const fileFilter = function(req, file, cb) {
const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
if (!allowedTypes.includes(file.mimetype)) {
const error = new Error('Wrong file type')
error.code = 'LIMIT_FILE_TYPES'
return cb(error, false)
}
cb(null, true)
}
const MAX_SIZE = 250000
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../frontend/assets/images')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer ({
storage: storage,
fileFilter,
limits: {
fileSize: MAX_SIZE
},
})
routes.post('/upload', upload.single('file'), (req, res) => {
res.json({ file: req.file })
})
return routes
}
As you can see I set the MAX_SIZE for my file uploads here so guess you can set any limit and as multer is handling it, it will over ride any limits set by express.
answered Nov 8 at 20:52
Andrew1325
21318
21318
Thanks for the clear answer, however my backend is in Rails unfortunately. I didn't account for the proxy which passes all requests to frontend/api would enforce a hard limit of 1mb. Altogether, your answer is a clear future reference.
– user1213904
Nov 8 at 21:49
add a comment |
Thanks for the clear answer, however my backend is in Rails unfortunately. I didn't account for the proxy which passes all requests to frontend/api would enforce a hard limit of 1mb. Altogether, your answer is a clear future reference.
– user1213904
Nov 8 at 21:49
Thanks for the clear answer, however my backend is in Rails unfortunately. I didn't account for the proxy which passes all requests to frontend/api would enforce a hard limit of 1mb. Altogether, your answer is a clear future reference.
– user1213904
Nov 8 at 21:49
Thanks for the clear answer, however my backend is in Rails unfortunately. I didn't account for the proxy which passes all requests to frontend/api would enforce a hard limit of 1mb. Altogether, your answer is a clear future reference.
– user1213904
Nov 8 at 21:49
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53195891%2fincrease-express-post-body-limit-to-proxied-api%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I've used what sounds like a similar setup to you and use multer and set my upload limits with it. I can post my code in an answer if you'd like to see it. I haven't tried it with files over 1mb so can't vouch for that but it may work. Let me know.
– Andrew1325
Nov 8 at 9:13
Would be nice to see an example, wonder if you hardcoded the endpoints or only used it as a proxy for parsing the body.
– user1213904
Nov 8 at 13:03
1
"which gets limited by the 1mb internal limit of express on all request bodies". There is no such thing, though. Perhaps one of the other middleware that you're using (
helmet,proxy) are responsible for imposing a limit. The stack trace of the error you're getting might provide some insight.– robertklep
Nov 8 at 21:08
@robertklep You were right, I could have sworn that I read that express imposes a limit somewhere, and come to think of it, being a default that is this hard to change wouldn't be very lucrative. The only express limit I could find is for json bodies: expressjs.com/en/api.html#express.json. In the end "express-force-https" sets a hard limit of 1mb for all proxied requests. Changing this fixed the issue. If you could make an answer of it, I would gladly accept it :).
– user1213904
Nov 8 at 21:39
@user1213904
express-force-httpsdoesn't set a limit either :)– robertklep
Nov 9 at 6:19