How to generate HTML with javascript on the server side (Node.js)? - javascript

I am trying to validate the user input from a register form, basically one of those forms when you create an account (signup), since after some research, people recommend to validate on both client side and server side to improve security.
Objective:
What I would like to achieve is when the user submits the form, therefore making a POST request to my server (the url can be /users/signup), the input will be validated with the use of express-validator. This way I can verify if the user specified a valid email, if the password and its confirmation match, etc, and if there are errors, I want to update the html page by adding a list of errors.
Note that I'd prefer to only update the necessary parts instead of the whole page to remove redundant rendering.
Now I know that I can use a template engine like Jade or Handlebars, which would result in code similar to this: res.render('signup', {errors: errors.array()}); where errors is a variable containing the validation result, and then the signup file with the code of the particular templating engine. But I would like to know if there are other ways of achieving the same without learning a new template engine, maybe similar to what JSX code looks like.
Here is the code I propose that uses a module with the necessary implementation (its not completed):
let express = require("express");
const html = require("../htmlGenerator/html");
const { check, validationResult } = require("express-validator/check");
let router = express.Router();
/* Create a new account/user. */
router.post("/signup", [
// Input Validation.
check("email", "Email is not valid").isEmail()
// ...
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty())
res.send(htmlErrorList(errors.array()));
//...
});
function htmlErrorList(errors) {
return html.ul(
errors.reduce((res, error) =>
res + html.li({class: "alert alert-danger"}, error.msg), "")
);
}
The idea of these functions, ul() and li(), is to create the HTML string with the given attributes (represented by an object with the properties being the attribute name and then its according value) and the content inside the tag we are creating.
The benefits I see with making or using a module that allows this sort of use are:
It promotes functional style coding
We don't need to learn a new template language to achieve something we can do with javascript
We can use the full power and capabilities of the javascript language, for example make a function that produces the HTML code of the navbar used in all end-points of the app.
Final notes:
I know that many times we want to access a database or any other data source, on the server, and pull some data to make complex computations in order to format it and display in a way the user understands. One of the solutions is, again the use of a template engine, and I'd like to know if the idea I suggest is valid and if there are any other solutions to this problem.
I appreciate any help or feedback on this subject.

This question is kind of "opinion" based so i will give my opinion.
1) Use a templating engine. It makes your life a lot easier.
2) Templating engines are easy to use. You can learn to use most them in half an hour. Making your own code would require a lot more time than just using an already proven method. Plus, other developers can easily read and edit the code if it's written using common tools whereas they would have to spend the time to learn whatever custom solution you have come up with.
3) Your example is so simple that you could generate that "HTML" just by concatenating strings and using template literals. If your example gets more complicated...than your solution would become much ... much harder to read and maintain.
4) You don't really need to "output" HTML for errors at all. Just output a JSON object and have the frontend handle it. e.g
res.send({errors: [{field: 'username', message: 'username is required'}, ...]});
5) You don't really need to output HTML for anything...other than the first page of your app/site. Keywords here are webpack + angular 2(angular is the "A" in MEAN stack).
It is used for a reason...it works and its good.
So, in summary, I would say, unless you have a really good reason to avoid template engines, I would go with a template engine.

Related

Gulp task to translate JS

I'm working on a JavaScript app and have so far entered all my strings as plain text.
This is starting to feel really hacky (I'm used to gettext) so I'd prefer to wrap them all in something like {{translatable_string}} and have a gulp task just search/replace them all during the build step.
So, my question is; is there a generic (no framework-specific like angular-gettext or something like that) gettext replacer out there?
Obviously it doesn't even have to be connected to JavaScript in any way, you should be able to run it on any file type and have {{translatable_string}}:s be translated.
You may want to look into using gulp-replace. As they explained in this answer, you should be able to use it to find and replace any string that you want in the stream.
I suggest a database of strings for your translations if dynamic generation of page content is possible for your app. Starting with English or whichever is normal but the need to localize content is a tough issue without a robust system. A simple MongoDB table can be used to store the content, and when the app needs an interface it can be loaded with the right localized strings. As a for instance:
if(err) alert("Please turn off caps lock");
could become:
if(err) alert(Please_turn_off_caps_lock.English);
If you are needing to build static pages with gulp, a database in conjunction with gulp-replace sounds interesting. Using gulp-data to call up and package the strings, you can then feed it to gulp-replace and alter the files. The extensible nature of databases or document stores enable you to expand your localization without hacking on individual files or trees all the time.
Try gulp-gettext-parser.
var gettext = require("gulp-gettext-parser");
var rename = require("gulp-rename");
gulp.task("gettext", function() {
return gulp.src("src/**/*.js")
.pipe(gettext())
.pipe(rename("bundle.po"))
.pipe(gulp.dest("dist/"));
});
Perhaps what you need is mustache.js, take a look: https://github.com/janl/mustache.js/
I'm not used to work with mustache, but I had to do some updates in a project done with it, and I was surprised the capabilities it have.
If you're familiar with jade (now renamed to pug), you'll find is something similar but at the end, you're not forced to generate only html files, you cand generate any kind of text file.
This blog could be helpful to understand the differences between some other templating languages over Nodejs: https://strongloop.com/strongblog/compare-javascript-templates-jade-mustache-dust/

Simple template engine for user-edited files

I am using nodeJS (server) and Dojo (client). I am writing a system that should allow users to create user-defined messages (they could be text-only email or SMS). I want to give a lot of flexibility. I would like to:
Pass the users a number of variables
Give the user a Web form
Allow the user to cycle through the data in the variables, print it, etc
The result of the script execution is a text file
This could even be used to allow them to create invoices. However, at this stage I am more focused on text.
I am thinking of allowing straight Javascript, and then eval() whatever they wrote in it. But... I am not sure.
What's the best practice solution for such a problem?
Don't use eval, read the following for why.
Why is using the JavaScript eval function a bad idea?
For JavaScript templating see the following list.
https://github.com/joyent/node/wiki/modules#wiki-templating

How to manage ASP.NET parameters and Javascript keys

So here is my scenario.
Im using ASP.NET MVC 3 along with HTML, CSS, JavaScript/JQuery to make a web application.
Im using Visual Studio 2010
We have already released the product (its in 1.0), however now that we are in "maintenance" mode for the project, I have a feeling that as the project has new features added, that it will be harder to maintain the set of constants between both the C# (ASP.NET MVC) and the JavaScript.
For example, in the JavaScript I would create a $.post and have it link to the MVC url Controller/Action and then I would pass in parameters { key1: value1, key2: value2}
The issue is that if the C# parameter names change or if the position of parameters in the signature change, I will only know at run-time that the JavaScript needs to be updated (im assuming that im a programmer that doesn't know the architecture well enough to do this before run time).
So my question is, how do you manage the JavaScript side more easily so that i can stay "in-sync" with changes made on the C# side. Can the compiler do this for me in some way, or is there a plug-in that can help me out?
Thanks.
Your question asks about syncing C# constants and JavaScript constants, but then also talks about parameter names and positions.
The positions of parameters matter less in the MVC world than the names, and I've not found a good way of keep those in sync short of extensive unit and integration testing. You are doing those tests, right? ;)
As far as actual constants and enums, I've taken to using T4 templates to generate both a .cs and a (namespaced) .js file for the constants/enums I need (in my case, out of a database, but could just as easily be anything else).
I can't think of any easy way, but here is something that may help. when I usually develop some website , first of all I try to write as least possible javascript code in views and have them all in .js file, this way you can be sure that you can reuse many codes and since all codes are pure javascript there won't be any problem you mentioned. I also keep the record of all actions with their controller and area name in database and use them for manage permissions and security issues. for your problem you can add all this method to database and later with a piece of code check if this method exist anymore.
adding to DB:(in base controller, so you don't need to do anything manually )
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var area = filterContext.RouteData.DataTokens["area"];
string areaName = area != null ? area.ToString() : "";
var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
string actionName = filterContext.ActionDescriptor.ActionName;
//Add to DB
base.OnActionExecuting(filterContext);
}
check if that exist:
bool exist = false;
try
{
HttpWebRequest request = (HttpWebRequest)System.Net.WebRequest.Create("http://www.example.com/image.jpg");
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
exist = response.StatusCode == HttpStatusCode.OK;
}
}
catch
{
}
Your best option is integration tests. You'll be able to test exactly the actions your users would do. Seleno is a good option (it wraps Selenium) for writing integration tests.
It's worth doing. If you have good integration test coverage you'll run into fewer bugs in production.

How can I make 'AJAX templates' in Pylons?

I've been getting into Pylons lately and was wondering how I could go about easily integrating AJAX functionality into my websites.
Basically, lets say I had a login form that usually gets accessed via site.com/user/login. Now, generally, this will be handled via something like:
class UserController(BaseController):
def login(self):
render('/login.html')
login.html would be a template that inherits the base, has a header, footer and navigation sidebar. A plani, simple website.
How could I AJAXify this? I would need to create two login.html templates, right? What would be a good way to handle the controller's login() method? Should I set a GET variable of something like &ajax=true then check for that when issuing render()?
I want a nice and clean way to choose how my controllers render content instead of some ugly hack (like the GET method above).
Thoughts?
All modern Javascript libraries set an "X-Requested-With: XMLHttpRequest" header in their AJAX wrappers. As a convenience, Pylons sets the request.is_xhr boolean if it finds this header.
Conditional inheritance is a little tricky in Mako because of how <%inherit> is handled, but here's what you do:
Change the render() call in your controller to render('/login.html', {'ajax': request.is_xhr})
In your template, separate out anything you don't want in your AJAX template using template inheritance.
Use an <%inherit> something like this:
<%inherit file="${None if context.get('ajax') else 'login_base.html'}"/>
(Note: There's nothing special about the render() syntax used. You could just as easily use c.ajax = request.is_xhr and context.get('c').ajax instead)
I'm not sure why your AJAX code would want to do a GET on that login page -- GET is only for getting information, and what info would the JS code client-side want to obtain from a login form?
Anyway, assuming there are pages that you want AJAX code to be able to GET in order to obtain useful info, I recommend a query string such as ?format=json to allow such requests to explicitly ask for "useful JSON-format info only, no decoration please".
Not only does this approach allow your app to know that this is an automated request (AJAX or otherwise, who cares? point is, no cosmetics are to be sent in response, just useful info!) but specifically that the requested format is JSON (so, should you ever want to supply XML or whatever as an alternative, there's an obvious growth path -- ?format=xml and the like).
There is nothing particularly Python-specific, much less Pylons-specific, in this -- it's the approach I would recommend for any "mixed" site (able, at least in some pages, to respond in more than one format, e.g. HTML with decorations or JSON, at clients' choice) no matter what sever-side language it was planning on using.
If your rendering is always of a form such as somefunction(sometemplate, somecontext), though, you may tweak things to ensure that the somefunction also gets the crucial bit about requested format -- if the requested format is JSON (or, who knows, in the future maybe XML or whatever) then somefunction knows it can ignore the template (which after all is or should be a purely view related functionality, and therefore should have presentation contents only) and just proceed to render the info that's in the context as JSON or whatever.
The author of Mako himself wrote a blog post that you might find interesting.
The main point is a function to render a single "def" of a template:
def render_def(template_name, name, **kwargs):
from pylons.templating import pylons_globals
globs = pylons_globals()
if kwargs:
globs = globs.copy()
globs.update(kwargs)
template = globs['app_globals'].mako_lookup.get_template(template_name).get_def(name)
return template.render(**globs)

Passing Python Data to JavaScript via Django

I'm using Django and Apache to serve webpages. My JavaScript code currently includes a data object with values to be displayed in various HTML widgets based on the user's selection from a menu of choices. I want to derive these data from a Python dictionary. I think I know how to embed the JavaScript code in the HTML, but how do I embed the data object in that script (on the fly) so the script's functions can use it?
Put another way, I want to create a JavaScript object or array from a Python dictionary, then insert that object into the JavaScript code, and then insert that JavaScript code into the HTML.
I suppose this structure (e.g., data embedded in variables in the JavaScript code) is suboptimal, but as a newbie I don't know the alternatives. I've seen write-ups of Django serialization functions, but these don't help me until I can get the data into my JavaScript code in the first place.
I'm not (yet) using a JavaScript library like jQuery.
n.b. see 2018 update at the bottom
I recommend against putting much JavaScript in your Django templates - it tends to be hard to write and debug, particularly as your project expands. Instead, try writing all of your JavaScript in a separate script file which your template loads and simply including just a JSON data object in the template. This allows you to do things like run your entire JavaScript app through something like JSLint, minify it, etc. and you can test it with a static HTML file without any dependencies on your Django app. Using a library like simplejson also saves you the time spent writing tedious serialization code.
If you aren't assuming that you're building an AJAX app this might simply be done like this:
In the view:
from django.utils import simplejson
def view(request, …):
js_data = simplejson.dumps(my_dict)
…
render_template_to_response("my_template.html", {"my_data": js_data, …})
In the template:
<script type="text/javascript">
data_from_django = {{ my_data }};
widget.init(data_from_django);
</script>
Note that the type of data matters: if my_data is a simple number or a string from a controlled source which doesn't contain HTML, such as a formatted date, no special handling is required. If it's possible to have untrusted data provided by a user you will need to sanitize it using something like the escape or escapejs filters and ensure that your JavaScript handles the data safely to avoid cross-site scripting attacks.
As far as dates go, you might also want to think about how you pass dates around. I've almost always found it easiest to pass them as Unix timestamps:
In Django:
time_t = time.mktime(my_date.timetuple())
In JavaScript, assuming you've done something like time_t = {{ time_t }} with the results of the snippet above:
my_date = new Date();
my_date.setTime(time_t*1000);
Finally, pay attention to UTC - you'll want to have the Python and Django date functions exchange data in UTC to avoid embarrassing shifts from the user's local time.
EDIT : Note that the setTime in javascript is in millisecond whereas the output of time.mktime is seconds. That's why we need to multiply by 1000
2018 Update: I still like JSON for complex values but in the intervening decade the HTML5 data API has attained near universal browser support and it's very convenient for passing simple (non-list/dict) values around, especially if you might want to have CSS rules apply based on those values and you don't care about unsupported versions of Internet Explorer.
<div id="my-widget" data-view-mode="tabular">…</div>
let myWidget = document.getElementById("my-widget");
console.log(myWidget.dataset.viewMode); // Prints tabular
somethingElse.addEventListener('click', evt => {
myWidget.dataset.viewMode = "list";
});
This is a neat way to expose data to CSS if you want to set the initial view state in your Django template and have it automatically update when JavaScript updates the data- attribute. I use this for things like hiding a progress widget until the user selects something to process or to conditionally show/hide errors based on fetch outcomes or even something like displaying an active record count using CSS like #some-element::after { content: attr(data-active-transfers); }.
For anyone who might be having a problems with this, be sure you are rendering your json object under safe mode in the template. You can manually set this like this
<script type="text/javascript">
data_from_django = {{ my_data|safe }};
widget.init(data_from_django);
</script>
As of mid-2018 the simplest approach is to use Python's JSON module, simplejson is now deprecated. Beware, that as #wilblack mentions you need to prevent Django's autoescaping either using safe filter or autoescape tag with an off option. In both cases in the view you add the contents of the dictionary to the context
viewset.py
import json
def get_context_data(self, **kwargs):
context['my_dictionary'] = json.dumps(self.object.mydict)
and then in the template you add as #wilblack suggested:
template.html
<script>
my_data = {{ my_dictionary|safe }};
</script>
Security warning:
json.dumps does not escape forward slashes: an attack is {'</script><script>alert(123);</script>': ''}. Same issue as in other answers. Added another answer hopefully fixing it.
You can include <script> tags inside your .html templates, and then build your data structures however is convenient for you. The template language isn't only for HTML, it can also do Javascript object literals.
And Paul is right: it might be best to use a json module to create a JSON string, then insert that string into the template. That will handle the quoting issues best, and deal with deep structures with ease.
It is suboptimal. Have you considered passing your data as JSON using django's built in serializer for that?
See the related response to this question. One option is to use jsonpickle to serialize between Python objects and JSON/Javascript objects. It wraps simplejson and handles things that are typically not accepted by simplejson.
Putting Java Script embedded into Django template is rather always bad idea.
Rather, because there are some exceptions from this rule.
Everything depends on the your Java Script code site and functionality.
It is better to have seperately static files, like JS, but the problem is that every seperate file needs another connect/GET/request/response mechanism. Sometimes for small one, two liners code os JS to put this into template, bun then use django templatetags mechanism - you can use is in other templates ;)
About objects - the same. If your site has AJAX construction/web2.0 like favour - you can achieve very good effect putting some count/math operation onto client side. If objects are small - embedded into template, if large - response them in another connection to avoid hangind page for user.
Fixing the security hole in the answers by #willblack and #Daniel_Kislyuk.
If the data is untrusted, you cannot just do
viewset.py
def get_context_data(self, **kwargs):
context['my_dictionary'] = json.dumps(self.object.mydict)
template.html
<script>
my_data = {{ my_dictionary|safe }};
</script>
because the data could be something like
{"</script><script>alert(123);</script>":""}
and forward slashes aren't escaped by default. Clearly the escaping by json.dumps may not 100% match the escaping in Javascript, which is where the problems come from.
Fixed solution
As far as I can tell, the following fixes the problem:
<script>
my_data = JSON.parse("{{ my_dictionary|escapejs }}");
</script>
If there are still issues, please post in the comments.

Categories

Resources