routes/index.js add the below line:router.post('/', function(req, res, next) {
console.log(req.body.hasOwnProperty('asdf'));
});
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<h1>req.body.hasOwnProperty is not a function</h1>
<h2></h2>
<pre></pre>
</body>
</html>
Why this happening? is this behaviour expected?
FYI for others; I tested this with node 1.8.4 and the latest node, both show me false.
What version of node and express-generator are you running?
Same here @notrab.
@vajahath My guess is that your OP does not contain all of the changes you made after running the generator. Maybe you could post the entire source on github and link us to it?
Well, assuming that the above was the _only_ change, then the answer would be that req.body is the result of Node.js core querystring module's parse function (https://nodejs.org/dist/latest-v6.x/docs/api/querystring.html#querystring_querystring_parse_str_sep_eq_options), which doesn't inherit from Object:
Note: The object returned by the querystring.parse() method does not prototypically extend from the JavaScript Object. This means that the typical Object methods such as obj.toString(), obj.hasOwnProperty(), and others are not defined and will not work.
woops! sorry for the delay. it was night here :night_with_stars:
@notrab here are the versions..
➜ ~/myGits node --version
v6.9.4
➜ ~/myGits express --version
4.14.1
➜ ~/myGits npm --version
4.4.4
➜ ~/myGits yarn --version
0.21.3
@wesleytodd happy to do that.. :smile_cat: here is the repo with the source code.
https://github.com/vajahath/express-issue-3264-info
$ node --version
v6.9.1
$ DEBUG=hoytest:* npm start
> [email protected] start ~/__test/express-issue-3264-info
> node ./bin/www
hoytest:server Listening on port 3000 +0ms
false
POST / - - ms - -
curl -X POST -H "Content-Type: application/json" -d '{"foo":"bar"}' "http://localhost:3000/"
I can confirm the same result as @wesleytodd with the same settings.
strange!!
Then how will we account for this
Note: The object returned by the querystring.parse() method does not prototypically extend from the JavaScript Object. This means that the typical Object methods such as obj.toString(), obj.hasOwnProperty(), and others are not defined and will not work.
as @dougwilson pointed out?
Ohhhhh, you sent a url encoded body. My curl above is incorrect, and this new one does exhibit that behavior, and it is the expected behavior due to what Doug mentioned.
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'foo=bar' "http://localhost:3000/"
@wesleytodd Ahh! missed it 😅
So this is the expected behavior. (it would be awesome if it wasn't. lol )
Now I can
router.post('/', function(req, res, next) {
req.body = JSON.parse(JSON.stringify(req.body));
console.log(req.body.hasOwnProperty('asdf'));
});
to fix the issue.
Not sure which is more performant, but you could also do:
Object.setPrototypeOf(req.body, {});
Either solution means that an external user could override prototype methods on your objects, and if you are not careful this is a security issue. If I were you I would not recommend doing either if you can help it. For example, with either one of the above methods, try this curl:
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'hasOwnProperty=bar' "http://localhost:3000/"
Should crash your app.
comming to your first part,
JSON.parse(JSON.stringify(req.body));
This method requires stringification and parsing, which are processing intensive tasks, I guess.
On the other hand, Mozilla says about
Object.setPrototypeOf(stuff..);
as
Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in obj.__proto__ = ... statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered. If you care about performance you should avoid setting the [[Prototype]] of an object. Instead, create a new object with the desired [[Prototype]] using Object.create().
Not sure what should I use.
second part
So how can I solve this issue safely?
req.body has the fields you are looking for. Personally I just do if (req.body.foo) // do stuff with foo. Or if its a boolean typeof req.body.foo !== 'undefined'alright.
I feel osm. Thanks everyone.
⭐️
Most helpful comment
@wesleytodd Ahh! missed it 😅
So this is the expected behavior. (it would be awesome if it wasn't. lol )
Now I can
to fix the issue.