I'm building a blog with Node.js, Express and MongoDB.
On the home page I have a button to load more posts. This works fine and I accomplish it with the following code:
jQuery
$("#load-more-posts").click(function() {
$.ajax({
url: '/load/posts/',
type: 'get',
dataType: 'html',
success: function(data) {
$("#primary").append(data);
},
data: {"passLastDate": lastDate}
});
return false;
});
Here's the route in app.js
app.get("/load/posts", routes.loadPosts);
And here's the view:
loadPosts: function(req, res) {
var lastDate;
lastDate = req.query.passLastDate;
return Post.find({
"published": true,
"publish_date": {
$lt: lastDate
}
}).sort('-publish_date').limit(1).execFind(function(err, posts) {
if (posts === []) {
console.log("thats it");
return res.render("thats-it", {
layout: false
});
} else {
lastDate = posts.slice(-1)[0].publish_date;
return res.render("more-posts", {
layout: false,
posts: posts,
lastDate: lastDate
});
}
});
}
Like I said, this all works great. However, if I copy the GET url from the console and paste it in the browser directly I get a returned HTML snippet. I suppose this is working like it should, but I don't want to return it. I don't think it's a security hazard, just seems a little inelegant.
Is there a way to block a direct request to this view?
BONUS
Here's something else that's strange, and makes this a two-part question. When I check for an empty post array in the if statement, Node ignores it. The console output shows posts = [] yet it skips right over it and then an error is thrown on lastDate = posts.slice(-1)[0].publish_date; I know JS behaves funny with empty values (null, undefined, empty string, etc.) but I've tried different ones with the same result. It seems like it's ignoring it completely. Am I taking crazy pills?
Is there a way to block a direct request to this view?
You could check and see if the request was performed using an AJAX call by checking for the x-requested-with header (which jQuery sends along):
loadPosts: function(req, res) {
if (req.headers['x-requested-with'] === 'XMLHttpRequest') {
// AJAX request
}
else {
// not an AJAX request
}
}
This shouldn't be used as a security measure (because it's not) but only as a way of checking to see if the request was made using AJAX or not.
As for your other problem, [] === [] is actually false (as is [] == []), so that's not a good way to see if an array is empty. I'd suggest you use:
if (!posts || posts.length === 0) {
// empty
}
You could use a session (which is initialized in the main page) to protect your snippets.
Add a middle-ware before the route to the snippets, the middle-ware checks the session token and redirects if no session is found.
It's pretty much the same as a system with data protected by login, and your main page login automatically for each user.
I can fetch some examples for you, leave a comment if you need it.
[BONUS]
Have you tried posts == [] orposts.length === 0 instead of posts === []?