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

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'});
});

Related

How to ignore specific files to be loaded when I use route parameters in Express

When I make a GET request with route parameters in express with mongoose like the following code, I sometimes see that the browser tries to load some unexpected files such as favicon.ico, robots.txt, humans.txt, sitemap.xml, ads.txt, etc., and 404 error shows up in the browser console.
app.get("/:userId", ...);
By refering to this Q&A, I figured out that if I don't use the route parameters right after the root route like the following code, it doesn't happen.
app.get("/user/:userId", ...);
In the same Q&A, however, there seem to be another way that uses req.url to ignore those unexpected files to be loaded, but it isn't explained in detail.
How do you do that?
All that's meant in that other answer is that you could examine req.url in your route handler and make sure it is not a known special name. In this specific case, it's probably simpler to use req.params.userId instead of req.url, but you could also use req.url in the same way.
const specials = new Set(["favicon.ico", "robots.txt", "humans.txt", "sitemap.xml", "ads.txt"]);
app.get("/:userId", (res, res, next) => {
// if it's a special URL, then skip it here
if (specials.has(req.params.userId)) {
next();
return;
}
// process your route here
});
Personally, I wouldn't recommend this solution because it presupposes a perfect knowledge of all possible special filenames. I don't use a top level wildcards ever because they ruin the ability to use your server for anything else.

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.

Render raw html in response with Express

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, '>');

Getting the mime type from a request in nodeJS

Im learning nodejs but I ran into a roadblock. Im trying to setup a simple server that will serve static files. My problem is that unless I explicitly type in the extension in the url, I cannot get the file extension. The httpheader 'content-type' comes in as undefined .
Here is my code, pretty simple:
var http = require("http"),
path = require("path"),
fs = require("fs");
var server = http.createServer(function(request, response){
console.log([path.extname(request.url), request.headers['content-type']]);
var fileName = path.basename(request.url) || "index.html",
filePath = __dirname + '/public/' + fileName;
console.log(filePath);
fs.readFile( filePath, function(err,data){
if (err) throw err
response.end(data);
});
})
server.listen(3000)
Any ideas?
FYI I dont just wanna dive into connect or other, I wanna know whats going on before I drop the grind and go straight to modules.
So static web servers generally don't do any deep magic. For example, nginx has a small mapping of file extensions to mime types here: http://trac.nginx.org/nginx/browser/nginx/conf/mime.types
There's likely also some fallback logic defaulting to html. You can also use a database of file "magic numbers" as is used by the file utility to look at the beginning of the file data and guess based on that.
But there's no magic here. It's basically
go by the file extension when available
maybe go by the beginning of the file content as next option
use a default of html because normally only html resources have URLs with no extensions, whereas images, css, js, fonts, multimedia, etc almost always do use file extensions in their URIs
Also note that browsers generally have fairly robust set of checks that will intepret files correctly even when Content-Type headers are mismatched with the actual response body data.

ExpressJS Route Parameter with Slash

Im using ExpressJS. I want pass url as parameter.
app.get('/s/:url', function(req, res) {
console.log(req.params.url);
});
/s/sg.com //sg.com
/s/www.sg.com //www.sg.com
/s/http://sg.com //http://sg.com
/s/http://sg.com/folder //http://sg.com/folder
How to correct the route such that everything afterr /s/ will be considered as paramenter including slashes.
Thanks
Uh, if you want to stick a URL inside of another URL, you need to URLencode it. If you want to stick one in their raw and suffer the consequences, just use app.get('/s/*'... and then manually parse out the url with req.url.slice(3). But hear me know and believe me later, URL Encoding is the right way to do this via the encodeURIComponent that is built in to JavaScript and works in both the browser and node.js.

Resources