Vue.js / Nginx / Node.js - 413 Request Entity Too Large - javascript

My frontend is made on Vue.js and is running on nginx in production. My nginx.conf looks like:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
client_max_body_size 100M;
# added for VueRouter
location / {
try_files $uri $uri/ /index.html;
}
}
In Node.js app I have this endpoint using multer to accept file:
// 100 MB
const upload = multer({ storage, limits: { fileSize: 100 * 1024 * 1024 } })
const router = express.Router()
router.post('/create', upload.single('file'), ImageController.create)
Also in app.js I have bodyParser set to 100 MB:
const app = express()
// Middleware
app.use(bodyParser.urlencoded({ limit: '100mb', extended: true, parameterLimit: 100000 }))
app.use(bodyParser.json({ limit: '100mb' }))
But I still get the error
413 Request Entity Too Large
Am I missing something?

I managed to fix it and the problem was nothing as I expected. In my VPS I create docker network nginx-proxy to link different ports to different domain names. I had to add client_max_body_size 100M; to nginx.conf of that container too!

Related

Serving a React app from Node while also having an API

So I am trying to have a Node/React setup on Ubuntu, inside an Nginx server.
The React app works fine, however when I try to have API endpoints (in Node) for the React app to call, those endpoints don't work - neither for the app, nor for going to those endpoints from a browser.
This is what some of the code looks like:
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'client/build')));
app.use(express.json());
app.get('/api/contactinfo', async (req, res) => {
let contactinfo = await Information.findAll({
plain: true,
attributes: ["phone", "email", "address"],
});
res.json(contactinfo);
});
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname + '/client/build/index.html'));
});
const port = process.env.PORT || 5000;
app.listen(port);
So for example, in this part, I might go to the React app's contact page (example.com/contact), and that loads fine. But the API call that the React app makes to the node server fails. So it seems like the React routing is working, but not the Node routing.
Likewise, if I go to just the Node API directly (example.com/api/contactinfo), that fails with a 502 bad gateway.
My Nginx setup looks like this:
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
I've also got some SSL cert setup stuff as well, though I'm not sure if that is relevant.
When I look at the Nginx error.log, this is what I see:
2020/09/02 15:36:54 [error] 1424#1424: *325 upstream prematurely closed connection while reading response header from upstream, client: 35.3.25.220, server: exampledomain.com, request: "GET /api/contactinfo HTTP/1.1", upstream: "http://127.0.0.1:5000/api/contactinfo", host: "exampledomain.com"
What exactly is causing my Node app API endpoints to fail? I've tried increasing the timeout, and several other things and nothing seems to be working - I've been trying to fix this problem for hours, but for some reason, despite the fact that I can successfully get React to load, I can't get any Node endpoints to do so.
How do I fix this?
I don't know the error in your implementation but here how I would do it.
// Nginx
server {
charset utf-8;
listen 80 default_server;
server_name _;
# front-end files
location / {
root /opt/front-end;
try_files $uri /index.html;
}
# node api reverse proxy
location /api/ {
proxy_pass http://localhost:5000/;
}
}
// folder structure
.
opt
+-- front-end
| +-- react app build
+-- back-end
+-- node app
// Node app
...
app.listen(5000);
Based on the article How to Deploy a MEAN Stack App to Amazon EC2
The “problem” is the certbot. If you have a self sign certificate it means that .... depending on how you configúrate certbot, basically now everything runs under port 443 not 80. So if on yow request you have some like `http://www domain com/api/endpoint. You’ll get the error you are getting. What you need to do is to use the https module from node.
import bodyParser from "body-parser";
import express from "express";
import fs from "fs";
import path from "path";
// import https
import https from "https";
import { routes } from "./routes";
import { logger } from "./utils/logger";
// The paths of those files keys will depend on where certbot stored them
const servOptions = {
cert: fs.readFileSync("/etc/letsencrypt/live/feikdomain.com/fullchain.pem"),
key: fs.readFileSync("/etc/letsencrypt/live/feikdomain.com/privkey.pem"),
ca: fs.readFileSync("/etc/letsencrypt/live/feikdomain.com/chain.pem"),
};
/**
* Createas an instance of the framework `fsexpress`.
*
* #returns {import("Express").Express} `express` instance.
*/
logger.info("express::expressApp");
const app: Express = express();
const build = path.join(__dirname, "../html");
app.use(express.static(build));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true, limit: "5m" }));
app.use("/static", express.static(build));
app.use(`${process.env.ENETO_CURRENT}`, routes());
app.use("*", function (req, res) {
return res.status(200).sendFile(`${build}/index.html`);
})
const secure = https.createServer(servOptions, app);
secure.listen(Number(process.env.PORT), () => {
console.log("servOptions: ", servOptions);
logger.info("APP RUNNING");
});
The issue was that I had a misunderstanding of how Node logging worked under Nginx.
I thought any problems or console logs with the Node setup would be logged to the nginx/error.log.
This was not in fact the case.
The Node setup had another problem, which made trying to access my endpoints crash.
The solution here is better logging that is not dependent on any sort of Nginx logs.
Solution
I just got this problem, and there are a couple of things you need.
First
you still need this
import bodyParser from "body-parser";
import express from "express";
import fs from "fs";
import path from "path";
// import https
import https from "https";
import { routes } from "./routes";
import { logger } from "./utils/logger";
// The paths of those files keys will depend on where certbot stored them
const servOptions = {
cert: fs.readFileSync("/etc/letsencrypt/live/feikdomain.com/fullchain.pem"),
key: fs.readFileSync("/etc/letsencrypt/live/feikdomain.com/privkey.pem"),
ca: fs.readFileSync("/etc/letsencrypt/live/feikdomain.com/chain.pem"),
};
/**
* Createas an instance of the framework `fsexpress`.
*
* #returns {import("Express").Express} `express` instance.
*/
logger.info("express::expressApp");
const app: Express = express();
const build = path.join(__dirname, "../html");
app.use(express.static(build));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true, limit: "5m" }));
app.use("/static", express.static(build));
app.use(`${process.env.ENETO_CURRENT}`, routes());
app.use("*", function (req, res) {
return res.status(200).sendFile(`${build}/index.html`);
})
const secure = https.createServer(servOptions, app);
secure.listen(Number(process.env.PORT), () => {
console.log("servOptions: ", servOptions);
logger.info("APP RUNNING");
});
Second
on yow location
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
more specific on the proxy_pass http://localhost:5000;
change the http or add an s at the end like this
proxy_pass https://localhost:5000;
location / {
proxy_pass https://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}

How to send headers in Express [MEAN]

I'm a beginner in Express. So I might've failed to frame the question properly. I have created a MEAN application wherein I've separated my frontend and backened. Frontend runs on port:4200 and server runs on port:3000. I wanted to run both frontend and backend on same port as part of deployment. I'm getting MIME type errors, someone told me that there is some problem with my server environment. Maybe I'm not sending headers properly. Here is my code:
I have mentioned tried solutions in the code itself as <----TRIED THIS
server.js
const express = require('express');
express.static.mime.define({'application/javascript': ['js']}); <----TRIED THIS
const bodyParser = require('body-parser');
const path = require('path');
// express.static.mime.define({'application/javascript': ['js']}); <----TRIED THIS
const api = require('./routes/api');
const PORT = 3000;
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', api);
app.get('/', function(req, res) {
// res.send('Hello from the server'); <----TRIED THIS
// res.writeHead(200, {'Content-Type': 'text/html'}); <----TRIED THIS
// res.set('Content-Type', 'text/plain'); <----TRIED THIS
// res.setHeader("Content-Type","application/json"); <----TRIED THIS
res.sendFile(path.join(__dirname, 'dist/application/index.html'));
})
app.listen(PORT, function() {
console.log('Server listening on PORT '+PORT);
});
api.js
For instance I'm showing you GET function only
const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const db = <my db string>;
const jwt = require('jsonwebtoken');
mongoose.connect(
...
)
function verifyToken(req, res, next) {
...
}
router.get('/myarticles', (req, res) => {
var person="Tanzeel Mirza";
console.log('Get request for tanzeel articles');
Article.find({contributor: person}, (error, article) => {
if(error) {
console.log(error)
}
else {
if(!article) {
res.status(401).send('Invalid email')
}
else if(2>4) {
console.log("test passed");
}
else {
res.json(article);
}
}
})
})
module.exports = router;
But still I'm getting
Loading module from “http://localhost:3000/runtime-xxx.js” was blocked because of a disallowed MIME type (“text/html”).
Loading module from “http://localhost:3000/polyfills-xxx.js” was blocked because of a disallowed MIME type (“text/html”).
Loading module from “http://localhost:3000/main-xxx.js” was blocked because of a disallowed MIME type (“text/html”).
Please correct me.
PS: I asked separate questions for MIME error here. But no answers.
Since your assets are inside dist/application folder, Use app.use(express.static(path.join(__dirname, 'dist/application')));
To match all web app routes, Use app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'dist/application/index.html'));
}).
This a generic route and will be called into action only if express can't find any other routes and always serve index.html. For example any valid /api route will never reach this handler, as there a specific route that handles it.
Final code for server.js
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const api = require('./routes/api');
const PORT = 3000;
const app = express();
app.use(express.static(path.join(__dirname, 'dist/application')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', api);
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'dist/application/index.html'));
})
app.listen(PORT, function() {
console.log('Server listening on PORT '+PORT);
});
A few points to not.
To serve static files, you need not set any headers manually. Express looks up the files in the folder (dist folder in your case) you set as static directory with the express.static middleware function. Express also sets the response headers based on the file extension.
So you don't need express.static.mime.define in your code anymore.
In your case you have defined app.use(express.static(path.join(__dirname, 'dist'))); which listens for static files at dist folder. In this app.use command, you haven't used a mount path which means that all the requests will go through the static middleware. If the middleware finds an asset with the same name, path and extension in dist folder it returns the file, else the request is passed to the other route handlers.
Also, If you are using static middleware, as long as there is an index.html in dist folder (immediate child of dist folder), your route handler for "/" will never get invoked as the response will be served by the middleware.
If you don't have an index html file in dist folder(immediate child of dist), but it's present somewhere in subfolders of dist, and still you need to access it using root path "/", only then you need a route handler for path "/" as below.
app.get("/", function(req, res) {
res.sendFile(path.join(__dirname, "dist/application/index.html"));
});
JS files referred using "./" in dist/application/index.html are referred relative to dist folder itself and NOT dist/application folder.
You can refer this REPL for updated code 👉.
https://repl.it/repls/SoreFearlessNagware
Try below urls
/api/myarticles - Rendered by "/api" route handler
/api/myarticles.js - Rendered by static asset middleware because the file exists in dist/api folder
/ - rendered using "/" route handler and res.sendFile because index.html doesn't exist in dist folder.
/test.js - Rendered using static middleware because file exists in dist folder
Additional links for reference.
https://expressjs.com/en/api.html#res.sendFile
https://expressjs.com/en/starter/static-files.html
1.Build your angular project, either inside or outside the server folder using ng build cmd.
2.To build your project inside server, change the dist-folder path in angular-cli.
3.To change path, either use cli cmd or edit the angular-cli.json file's "outDir": "./location/toYour/dist"
Or by using this cli cmd ng build --output-path=dist/example/
4.Then In your server root file include the static build/dist folder using express.
5.Like this app.use(express.static(path.join( 'your path to static folder')));
6.Now restart your server.

500 error when attempting to .get() another file in Express

I am attempting to do some simple Express routing. However, whenever I attempt to retrieve data to link to a new page on my website, I get a 500 error instead. My Index.js file is for routing.
Index.js file:
var express = require('express');
var router = express.Router();
var db = require('monk')('localhost:27017/');
var userData = db.get('user-data');
var app = require('express')();
router.get('/', function(req,res,next){
res.render('layout');
});
router.get('/1', function(req,res,next){
res.render('layout2');
});
module.exports = router;
My app.js file contains my app engine, which is in fact set up for handlebars:
app.engine('hbs', hbs({extname: 'hbs', defaultLayout: 'layout', layoutsDir: __dirname + '/views/layouts/'}));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
Here is what the error says:
GET / 500 33.765 ms - 20931
GET /stylesheets/style.css 304 1.633 ms - -
GET /stylesheets/print2.css 304 1.219 ms - -
I expect that when I type in localhost:8000/1 the site will render layout2.hbs - but I get a 500 error instead.
GET /stylesheets/style.css 304 1.633 ms - -
GET /stylesheets/print2.css 304 1.219 ms - -
These error may be because you have not specified static folder for your app.
Create a static public folder in your project root directory.
Add all your local css, js, and images in a file named "public" and add the below middleware code in your index.js file.
app.use(express.static("public"))
Hope this will solve our problem.

express.js compress middleware do not work

I have the following middlewares in my app:
app.use(express.favicon(__dirname + '/static/public/images/favicon.ico'));
app.use(express.compress());
app.use(express.json());
app.use(express.urlencoded());
app.use(express.cookieParser('SECRET!'));
app.use(express.static(__dirname + config.static_path, {maxAge: 365 * 86400000}));
app.use(express.session({secret: 'SECRET!'}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
headers example:
But the static content do not compressing. What could be the problem?
There are several reasons why your static content may not get compressed:
express.compress maintains a minimum file size threshold; files with a size below this threshold (default: 1024 bytes) won't get compressed;
express.compress also maintains a whitelist of content types to compress; if you're serving files with a content type that's not on that list, it won't get compressed either;
To fix:
app.use(express.compress({
threshold : 0, // or whatever you want the lower threshold to be
filter : function(req, res) {
var ct = res.get('content-type');
// return `true` for content types that you want to compress,
// `false` otherwise
...
}
}));
(as a reference, this is the default filter function used)
The problem was in rerouting to 80-th port like :
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
Thanks to #robertklep for help!

Error: request entity too large

I'm receiving the following error with express:
Error: request entity too large
at module.exports (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/node_modules/raw-body/index.js:16:15)
at json (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/middleware/json.js:60:5)
at Object.bodyParser [as handle] (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:53:5)
at next (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/proto.js:193:15)
at Object.cookieParser [as handle] (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js:60:5)
at next (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/proto.js:193:15)
at Object.logger (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/middleware/logger.js:158:5)
at next (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/proto.js:193:15)
at Object.staticMiddleware [as handle] (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/middleware/static.js:55:61)
at next (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/proto.js:193:15)
TypeError: /Users/michaeljames/Documents/Projects/Proj/mean/app/views/includes/foot.jade:31
29| script(type="text/javascript", src="/js/socketio/connect.js")
30|
> 31| if (req.host='localhost')
32| //Livereload script rendered
33| script(type='text/javascript', src='http://localhost:35729/livereload.js')
34|
Cannot set property 'host' of undefined
at eval (eval at <anonymous> (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/jade/lib/jade.js:152:8), <anonymous>:273:15)
at /Users/michaeljames/Documents/Projects/Proj/mean/node_modules/jade/lib/jade.js:153:35
at Object.exports.render (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/jade/lib/jade.js:197:10)
at Object.exports.renderFile (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/jade/lib/jade.js:233:18)
at View.exports.renderFile [as engine] (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/jade/lib/jade.js:218:21)
at View.render (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/lib/view.js:76:8)
at Function.app.render (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/lib/application.js:504:10)
at ServerResponse.res.render (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/lib/response.js:801:7)
at Object.handle (/Users/michaeljames/Documents/Projects/Proj/mean/config/express.js:82:29)
at next (/Users/michaeljames/Documents/Projects/Proj/mean/node_modules/express/node_modules/connect/lib/proto.js:188:17)
POST /api/0.1/people 500 618ms
I am using meanstack. I have the following use statements in my express.js
//Set Request Size Limit
app.use(express.limit(100000000));
Within fiddler I can see the content-length header with a value of: 1078702
I believe this is in octets, this is 1.0787 megabytes.
I have no idea why express is not letting me post the json array I was posting previously in another express project that was not using the mean stack project structure.
I had the same error recently, and all the solutions I've found did not work.
After some digging, I found that setting app.use(express.bodyParser({limit: '50mb'})); did set the limit correctly.
When adding a console.log('Limit file size: '+limit); in node_modules/express/node_modules/connect/lib/middleware/json.js:46 and restarting node, I get this output in the console:
Limit file size: 1048576
connect.multipart() will be removed in connect 3.0
visit https://github.com/senchalabs/connect/wiki/Connect-3.0 for alternatives
connect.limit() will be removed in connect 3.0
Limit file size: 52428800
Express server listening on port 3002
We can see that at first, when loading the connect module, the limit is set to 1mb (1048576 bytes). Then when I set the limit, the console.log is called again and this time the limit is 52428800 (50mb). However, I still get a 413 Request entity too large.
Then I added console.log('Limit file size: '+limit); in node_modules/express/node_modules/connect/node_modules/raw-body/index.js:10 and saw another line in the console when calling the route with a big request (before the error output) :
Limit file size: 1048576
This means that somehow, somewhere, connect resets the limit parameter and ignores what we specified. I tried specifying the bodyParser parameters in the route definition individually, but no luck either.
While I did not find any proper way to set it permanently, you can "patch" it in the module directly. If you are using Express 3.4.4, add this at line 46 of node_modules/express/node_modules/connect/lib/middleware/json.js :
limit = 52428800; // for 50mb, this corresponds to the size in bytes
The line number might differ if you don't run the same version of Express.
Please note that this is bad practice and it will be overwritten if you update your module.
So this temporary solution works for now, but as soon as a solution is found (or the module fixed, in case it's a module problem) you should update your code accordingly.
I have opened an issue on their GitHub about this problem.
[edit - found the solution]
After some research and testing, I found that when debugging, I added app.use(express.bodyParser({limit: '50mb'}));, but after app.use(express.json());. Express would then set the global limit to 1mb because the first parser he encountered when running the script was express.json(). Moving bodyParser above it did the trick.
That said, the bodyParser() method will be deprecated in Connect 3.0 and should not be used. Instead, you should declare your parsers explicitly, like so :
app.use(express.json({limit: '50mb'}));
app.use(express.urlencoded({limit: '50mb'}));
In case you need multipart (for file uploads) see this post.
[second edit]
Note that in Express 4, instead of express.json() and express.urlencoded(), you must require the body-parser module and use its json() and urlencoded() methods, like so:
var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
If the extended option is not explicitly defined for bodyParser.urlencoded(), it will throw a warning (body-parser deprecated undefined extended: provide extended option). This is because this option will be required in the next version and will not be optional anymore. For more info on the extended option, you can refer to the readme of body-parser.
[third edit]
It seems that in Express v4.16.0 onwards, we can go back to the initial way of doing this (thanks to #GBMan for the tip):
app.use(express.json({limit: '50mb'}));
app.use(express.urlencoded({limit: '50mb'}));
In my case it was not enough to add these lines :
var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
I tried adding the parameterLimit option on urlencoded function as the documentation says and error no longer appears.
The parameterLimit option controls the maximum number of parameters
that are allowed in the URL-encoded data. If a request contains more
parameters than this value, a 413 will be returned to the client.
Defaults to 1000.
Try with this code:
var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: "50mb"}));
app.use(bodyParser.urlencoded({limit: "50mb", extended: true, parameterLimit:50000}));
If someone tried all the answers, but hadn't had any success yet and uses NGINX to host the site add this line to /etc/nginx/sites-available
client_max_body_size 100M; #100mb
I don't think this is the express global size limit, but specifically the connect.json middleware limit. This is 1MB by default when you use express.bodyParser() and don't provide a limit option.
Try:
app.post('/api/0.1/people', express.bodyParser({limit: '5mb'}), yourHandler);
For express ~4.16.0, express.json with limit works directly
app.use(express.json({limit: '50mb'}));
in my case .. setting parameterLimit:50000 fixed the problem
app.use( bodyParser.json({limit: '50mb'}) );
app.use(bodyParser.urlencoded({
limit: '50mb',
extended: true,
parameterLimit:50000
}));
The following worked for me... Just use
app.use(bodyParser({limit: '50mb'}));
that's it.
Tried all above and none worked. Found that even though we use like the following,
app.use(bodyParser());
app.use(bodyParser({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb'}));
only the 1st app.use(bodyParser()); one gets defined and the latter two lines were ignored.
Refer: https://github.com/expressjs/body-parser/issues/176 >> see 'dougwilson commented on Jun 17, 2016'
2016, none of the above worked for me until i explicity set the 'type' in addition to the 'limit' for bodyparser, example:
var app = express();
var jsonParser = bodyParser.json({limit:1024*1024*20, type:'application/json'});
var urlencodedParser = bodyParser.urlencoded({ extended:true,limit:1024*1024*20,type:'application/x-www-form-urlencoded' })
app.use(jsonParser);
app.use(urlencodedParser);
The setting below has worked for me
Express 4.16.1
app.use(bodyParser.json({ limit: '50mb' }))
app.use(bodyParser.urlencoded({
limit: '50mb',
extended: false,
}))
Nginx
client_max_body_size 50m;
client_body_temp_path /data/temp;
In my case the problem was on Nginx configuration. To solve it I have to edit the file: /etc/nginx/nginx.conf and add this line inside server block:
client_max_body_size 5M;
Restart Nginx and the problems its gone
sudo systemctl restart nginx
After דo many tries I got my solution
I have commented this line
app.use(bodyParser.json());
and I put
app.use(bodyParser.json({limit: '50mb'}))
Then it works
A slightly different approach - the payload is too BIG
All the helpful answers so far deal with increasing the payload limit. But it might also be the case that the payload is indeed too big but for no good reason. If there's no valid reason for it to be, consider looking into why it's so bloated in the first place.
Our own experience
For example, in our case, an Angular app was greedily sending an entire object in the payload. When one bloated and redundant property was removed, the payload size was reduced by a factor of a 100. This significantly improved performance and resolved the 413 error.
Pass the below configs to your server to increase your request size.
app.use(express.json({ extended: false, limit: '50mb' }))
app.use(express.urlencoded({ limit: '50mb', extended: false, parameterLimit: 50000 }))
Little old post but I had the same problem
Using express 4.+
my code looks like this and it works great after two days of extensive testing.
var url = require('url'),
homePath = __dirname + '/../',
apiV1 = require(homePath + 'api/v1/start'),
bodyParser = require('body-parser').json({limit:'100mb'});
module.exports = function(app){
app.get('/', function (req, res) {
res.render( homePath + 'public/template/index');
});
app.get('/api/v1/', function (req, res) {
var query = url.parse(req.url).query;
if ( !query ) {
res.redirect('/');
}
apiV1( 'GET', query, function (response) {
res.json(response);
});
});
app.get('*', function (req,res) {
res.redirect('/');
});
app.post('/api/v1/', bodyParser, function (req, res) {
if ( !req.body ) {
res.json({
status: 'error',
response: 'No data to parse'
});
}
apiV1( 'POST', req.body, function (response) {
res.json(response);
});
});
};
I've used another practice for this problem with multer dependancie.
Example:
multer = require('multer');
var uploading = multer({
limits: {fileSize: 1000000, files:1},
});
exports.uploadpictureone = function(req, res) {
cloudinary.uploader.upload(req.body.url, function(result) {
res.send(result);
});
};
module.exports = function(app) {
app.route('/api/upload', uploading).all(uploadPolicy.isAllowed)
.post(upload.uploadpictureone);
};
If you are using express.json() and bodyParser together it will give error as express sets its own limit.
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
remove above code and just add below code
app.use(bodyParser.json({ limit: "200mb" }));
app.use(bodyParser.urlencoded({ limit: "200mb", extended: true, parameterLimit: 1000000 }));
After trying everything in this post, i was unsuccessful. But I found a solution that worked for me.
I was able to solve it without using the body-parser and only with the express.
It looked like this:
const express = require('express');
const app = express();
app.use(express.json({limit: '25mb'}));
app.use(express.urlencoded({limit: '25mb', extended: true}));
Don't forget to use extended: true to remove the deprecated message from the console.
Just adding this one line must solve it actually
app.use(express.json({limit: '50mb'}));
Also recommend you guys to send the whole image to the backend then convert it rather then sending the data from the frontend
for me following snippet solved the problem.
var bodyParser = require('body-parser');
app.use(bodyParser.json({limit: '50mb'}));
In my case removing Content-type from the request headers worked.
I too faced that issue, I was making a silly mistake by repeating the app.use(bodyParser.json()) like below:
app.use(bodyParser.json())
app.use(bodyParser.json({ limit: '50mb' }))
by removing app.use(bodyParser.json()), solved the problem.
I faced the same issue recently and bellow solution workes for me.
Dependency :
express >> version : 4.17.1
body-parser >> version": 1.19.0
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
For understanding :
HTTP 431
The HTTP 413 Payload Too Large response status code indicates that the
request entity is larger than limits defined by server; the server
might close the connection or return a Retry-After header field.
Work for me:
Config nginx max file zise
[https://patriciahillebrandt.com/nginx-413-request-entity-too-large/][1]
and
app.use(bodyParser.json({ limit: "200mb" }));
app.use(bodyParser.urlencoded({ limit: "200mb", extended: true, parameterLimit: 1000000 }));
To add to Alexander's answer.
By default, NGINX has an upload limit of 1 MB per file. By limiting the file size of uploads, you can prevent some types of Denial-of-service (DOS) attacks and many other issues.
So when you try to upload a file above the 1MB limit you will run into a 413 error.
By editing client_max_body_size, you can adjust the file upload size. Use the http, server, or location block to edit client_max_body_size.
server {
server_name example.com;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080;
client_max_body_size 20M;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/infohob.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/infohob.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
Reference: Limit File Upload Size in NGINX
The better use you can specify the limit of your file size as it is shown in the given lines:
app.use(bodyParser.json({limit: '10mb', extended: true}))
app.use(bodyParser.urlencoded({limit: '10mb', extended: true}))
You can also change the default setting in node-modules body-parser then in the lib folder, there are JSON and text file. Then change limit here. Actually, this condition pass if you don't pass the limit parameter in the given line
app.use(bodyParser.json({limit: '10mb', extended: true})).
This issue happens in two cases:
1- request body is too large and server cannot process this large data. this will serve it
app.use(express.json({limit: '50mb'}));
2- req.cookies is too large. When testing different next.js applications on the same browser, each time each app was starting on a different port if there were running some apps. Same app might end up starting at port 3000-3005 range. That means if your app saves cookie, that cookie will be saved for each port. Let's say you started 5 different apps at localhost:3000, and each one saved a cookie. If you make a request, all the cookies will be attached to the request object, in this case you will not able to process even small size of post.body. Solution is you have to delete all the cookies
Express 4.17.1
app.use( express.urlencoded( {
extended: true,
limit: '50mb'
} ) )
Demo csb
Following code resolved my issue:
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false, limit: '5mb' });
For me the main trick is
app.use(bodyParser.json({
limit: '20mb'
}));
app.use(bodyParser.urlencoded({
limit: '20mb',
parameterLimit: 100000,
extended: true
}));
bodyParse.json first
bodyParse.urlencoded second
For those who start the NodeJS app in Azure under IIS, do not forget to modify web.config as explained here Azure App Service IIS "maxRequestLength" setting

Categories

Resources