Render raw html in response with Express - node.js

I would like to know how to render a raw HTML string in a response with Express.
My question is different from the others because I am not trying to render a raw HTML template; rather I just want to render a single raw HTML string.
Here is what I have tried in my route file.
router.get('/myRoute', function (req, res, next) {
var someHTML = "bar"
res.send(someHTML);
});
But when I point my browser to this route, I see a hyperlink, instead of a raw HTML string. I have tried to set the content-type to text by doing: res.setHeader('Content-Type', 'text'); with no avail.
Any suggestions?

For others arriving here; this worked best for me:
res.set('Content-Type', 'text/html');
res.send(Buffer.from('<h2>Test String</h2>'));
Edit:
And if your issue is escaping certain characters, then try using template literals: Template literals

The best way to do this is, assuming you're using callback style, declare var output=""....then go through appending what you need to the output var with +=.... use a template literal (new line doesn't matter ${variables in here}) if it's a large string... then res.writeHead(200,{Content-Type: text/html); res.end(output)

Encode the HTML before sending it. Someone made a Gist for this: https://gist.github.com/mikedeboer/1aa7cd2bbcb8e0abc16a

Just add tags around it
someHTML = "<plaintext>" + someHTML + "</plaintext>";
Just a word of caution that the plaintext is considered obsolete which means browser vendors have no obligation to implement them. However ,it still works on major browsers.
Another way you could do it is
someHTML = someHTML.replace(/</g, '<').replace(/>/g, '>');

Related

Handling UTF8 characters in express route parameters

I'm having an issue with a NodeJS REST api created using express.
I have two calls, a get and a post set up like this:
router.get('/:id', (request, response) => {
console.log(request.params.id);
});
router.post('/:id', (request, response) => {
console.log(request.params.id);
});
now, I want the ID to be able to contain special characters (UTF8).
The problem is, when I use postman to test the requests, it looks like they are encoded very differently:
GET http://localhost:3000/api/â outputs â
POST http://localhost:3000/api/â outputs â
Does anyone have any idea what I am missing here?
I must mention that the post call also contains a file upload so the content type will be multipart/form-data
You should encode your URL on the client and decode it on the server. See the following articles:
What is the proper way to URL encode Unicode characters?
Can urls have UTF-8 characters?
Which characters make a URL invalid?
For JavaScript, encodeURI may come in handy.
It looks like postman does UTF-8 encoding but NOT proper url encoding. Consequently, what you type in the request url box translates to something different than what would happen if you typed that url in a browser.
I'm requesting: GET localhost/ä but it encodes it on the wire as localhost/ä
(This is now an invalid URL because it contains non ascii characters)
But when I type localhost/ä in to google chrome, it correctly encodes the request as localhost/%C3%A4
So you could try manually url encoding your request to http://localhost:3000/api/%C3%A2
In my opinion this is a bug (perhaps a regression). I am using the latest version of PostMan v7.11.0 on MacOS.
Does anyone have any idea what I am missing here?
yeah, it doesn't output â, it outputs â, but whatever you're checking the result with, think you're reading something else (iso-8859-1 maybe?), not UTF-8, and renders it as â
Most likely, you're viewing the result in a web browser, and the web server is sending the wrong Content-Type header. try doing header("Content-type: text/plain;charset=utf-8"); or header("Content-type: text/html;charset=utf-8"); , then your browser should render your â correctly.

how to fetch req.params whatever it was

I'm working on a url shortener api. The problem i'm facing is that if I pass a parameter like https://www.youtube.com/watch?v=8aGhZQkoFbQ then req.params.url will only be equal to https://www.youtube.com/watch. I've looked a lot on stackoverflow and all the answers are similar but not what I'm looking for.
I want to parse the url parameter and get the characters it contains.
This is the URI i'm using right now
router.route('/add/:url(*)')
You can try something like this:
app.get(/[/]add[/].*/, function (req, res) {
var uri = req.originalUrl.replace(/^[/][^/]*[/]*/, '');
console.log(uri);
res.end();
});
Maybe you're wanting the query part of the URL? Take a look at req.query docs (and other parts of the request) and read about the parts of the URI or more formal definitions on wikipedia. Having the correct names will help you understand the Express.js docs.
From express.js docs:
// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret"
From wikipedia:
scheme:[//[user:password#]host[:port]][/]path[?query][#fragment]

How to get i18next-node to display umlauts the right way?

I searched around quite a bit but couldn't find a solution for my problem.
My app uses i18next and it works fine except for one issue: german umlauts (ü,ö,ä) are displayed as �.
I don't understand were I got it wrong, since this example app has no problem with umlauts: http://i18next-example1.eu01.aws.af.cm/?setLng=de-DE (github: https://github.com/rbeere/i18next-jade-express-sample)
How can I figure this one out?
The culprit might be:
The Translation.json file is not saved as UTF8.
If any specific
fonts are used, their Unicode support is very very limited (this is
very unlikely with modern fonts).
layout.jade file doesn't declare the page encoding. Therefore it's up to the browser to auto-detect it. No matter if this fixes the problem or not, it's a good practice to declare the page encoding in the header:
meta(http-equiv="Content-Type",content="text/html; charset=utf-8")
Content-Type HTTP header field is not set properly. Change the HTTP response as follows:
app.get('/', function(req, res) {
res.header("Content-Type", "text/html; charset=utf-8");
res.render('index', { title: 'Localization with Express, Jade and i18next-node'});
});

Get return value of `include` in jade template

What I basically try to accomplish is to re-use jade partials/templates when getting data through a socket connection. Non working example:
socket.on('company_created', function(company) {
var html = include _company;
$('#companies ul').append(html);
});
Normally I had to create a new li and set the content like so (which is working as expected):
$('#companies ul').append($('<li>').text(company.name));
This is okay for a simple list, but if I had complexer list and stuff, this could get messy pretty quick, plus I had to write plain HTML again, so I figured re-using my already existing jade templates with all their goodness would be awesome, but had not luck, yet.
Any clue?
PS: Please do not tell my to use Ember, Backbone, Derby, Meteor, Angular or whatsoever.
Thanks in advance!
You can compile your jade sources to JS with jade.compile. Then include these sources in the client-side javascript, include jade's runtime.min.js, and refer to your jade templates as to normal JS functions in your client-side code.
For example,
server.js
app.get('/templates/:template.js', function (req, res) {
var template = req.params.template;
response.end([
"window.templates = window.templates || {};",
"window.templates[\"" + template + "\"] = " + jade.compile(template + ".jade", { client: true; });
].join("\r\n"));
});
client.js
$(function() { $("#placeholder").html(window.templates["content"]({user: "Daniel" })); });
content.jade
h1: Hello #{user}!
index.jade
!!!
html
head
script(src='/lib/jquery/jquery.js')
script(src='/lib/jade/runtime.min.js')
script(src='/templates/content.js')
script(src='/scripts/client.js')
body
#placeholder
Note that the code above might be syntactically incorrect and is provided solely to illustrate the idea.
we have a build step that compiles them to functions sort of like penartur mentioned. I dont use extend or include (which dont work on the client anyway ATM), but personally I find we have absolutely no need for that on the client at all since the DOM provides all the separation we need.

Jade template, how to pass concrete object to pages?

I have a jade template for my node.js project. I would like to send an object to the jade template and pass it to a function inside the page (to render something).
I am sure I send the right stuff from the server like this
res.render(__dirname + '/pages/viz.jade', {
vizJson: newJson,
});
in the client I do something like this:
script
sunburst(#{vizJson})
Thus, inside a script function, I want to call a function that creates my visualization with some json I created on the server side.
The problem is that when rendered I have something like sunburst([Object object]). I also tried to send the stringified version of the JSON but when I do JSON.parse(#{vizJson}) it complains like Unexpected token &.
The json I send is always different and has different level of depths.
Does anyone knows what to do?
Thanks
I hope this is going to help someone. I solved it like this:
script
sunburst(!{JSON.stringify(vizJson)})
Notice the ! and the {...} wrapping the stringify method.
For this to work, you need to stringify on the server.
res.render(__dirname + '/pages/viz.jade', {
vizJson: JSON.stringify(newJson),
});
Then, as you mentioned, parse the JSON on the client.
script
sunburst(JSON.parse(#{vizJson}))
Hope that helps!
Oddly enough, for me the solution involved no calls to JSON.parse. I stringified my object on the server and just used the !{vizJson} method and got my object clientside.
Per the docs, unescaped string interpolation: http://jade-lang.com/reference/interpolation/
On the JS side, you send back
res.render(__dirname + '/pages/viz.jade', {
vizJson: JSON.stringify(newJson),
});
On the HTML side, I have found that something like:
JSON.parse( '!{vizJson}' )
works.

Resources