How to upload and display a file in Node.js? - node.js

I'm new to Node and have some problems with uploading files. I'm trying to to upload images (both jpg and png) and text files in text/plain and then display them at the post-route ('/upload)'. I've tried both multer and formidable but cannot get it right. Would really appreciate some help.
I tried all different kinds of events and callbacks, but I'm missing some crucial steps. Here is the html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Testform</title>
</head>
<body>
<form method="post" enctype="multipart/form-data"
action="/upload">
<div>
<input type="file" name="file" size="35">
</div>
<button type="submit" value="Click me" name="submit-btn">Click me</button>
</form>
</body>
</html>
And here is the server code:
const formidable = require('formidable')
const express = require('express')
const path = require('path')
const app = express()
app.get('/', (req, res) => {
res.sendFile(path.resolve('views', 'index.html'))
})
app.post('/upload', (req, res) => {
const form = new formidable.IncomingForm()
form.uploadDir = __dirname + '/uploads/'
form.parse(req)
form.on('fileBegin', (name, file) => {
file.path = form.uploadDir + file.name
res.write(`<img src="./uploads/${file.name}">`)
res.end()
})
})
app.listen(3000)
My root folder contains app.js, views/index.html, and a directory called uploads.
The code is my test case for image uploads. When I run the program a file with the correct name and content get uploaded into the directory './uploads'. However, I cannot see the uploaded image in the response of the post request ('/upload'). Would be great if anyone could help me with this and also for other text files (text/plain). Cheers!

In the response of the request you can send values, so something like res.end(value here) works!

Related

Node, Ejs, Express, passing variables to partial views. issues with re-using the same code in the express routes. Need to condense code

I am a newbie to node, express and ejs. I am creating a blog website project. I want to make use of EJS partials to stop repeating elements of code on my website. The simplified structure is
Blog
--js
--sql-helpers.js
--routes
--routes.js
--views
--homepage.ejs
--aboutpage.ejs
--header(Partial).ejs
The partial header ejs file is to be used on all webpages as it displays the title and author of the blog.
Here is a snippet of code from the routes file:
routes.js
router.get('/homepage', (req, res) => {
const sql = 'SELECT * FROM authors';
global.db.all(sql,[], function(err,rows){
const blogInfo = rows[0];
const params = {
authorName:blogInfo.author_name,
authorBlogTitle:blogInfo.authors_blog_title,
authorSubtitle:blogInfo.authors_blog_subtitle
};
res.render('homepage', params);
});
});
router.get('/aboutpage', (req,res) => {
const sql = 'SELECT * FROM authors';
global.db.all(sql,[], function(err,rows){
const blogInfo = rows[0];
const params = {
authorName:blogInfo.author_name,
authorBlogTitle:blogInfo.authors_blog_title,
authorSubtitle:blogInfo.authors_blog_subtitle
};
res.render('aboutpage', params);
});
});
As you can see I am having to re-use the same code in each of the routes to fill the variables in the header(partial).ejs file.
The homepage.ejs file code is as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home Page</title>
</head>
<body>
<%- include('header(Partial)') %>
</body>
</html>
The header(partial).ejs file looks like this:
<header>
<section>
<h1 ><strong><%= authorBlogTitle %></strong></h1>
<span><%= authorSubtitle %></span>
<p ><small><%= authorName %></small></p>
</section>
</header>
To try and stop re-peating the same code i created a sql-helpers js file. as follows
const blogheader = function(callback){
const sql = 'SELECT * FROM authors';
global.db.all(sql,[], function(err,rows){
const blogInfo = rows[0];
const params = {
authorName:blogInfo.author_name,
authorBlogTitle:blogInfo.authors_blog_title,
authorSubtitle:blogInfo.authors_blog_subtitle
};
callback(params);
});
}
module.exports = {blogheader};
updated routes.js file:
const helpers = require("../public/js/sql_scripts");
router.get('/settings', (req,res) => {
let bloginfo = helpers.blogheader()
res.render('settings', blogheader);
});
My problems is I when i try and use this sql helper function in the routes I am getting a undefined value. Is this the best way to do it? How can wrap up my sql query so i dont have to repeat the same code in the routes? Is there a better way to use ejs partials?
I have been stuck on this issue for a number of days, searching the internet for an answer but I just havent found anything that helps me.

Why res.send( string ) download a file

I have an app where I want to render static html with express.
I know about res.sendFile() but that is not what I want to use. I want to load my files using fs and send them using res.send()
I do something like this :
fileFoo = fs.readFileSync('./html/foo.html', 'utf-8');
fileBar = fs.readFileSync('./html/bar.html', 'utf-8');
app = express()
app.get('/foo', (req, res) => res.send(fileFoo));
app.get('/foo/bar', (req, res) => res.send(fileBar));
With 2 very simple html files
foo.html
<html>
<head>
<title>FOO</title>
</head>
<body>
<h1>FOO</h1>
bar
</body>
</html>
bar.html
<html>
<head>
<title>BAR</title>
</head>
<body>
<h1>BAR</h1>
</body>
</html>
When I go to /foo I got a HTML rendered.
If I click on bar I do not get a new HTML page rendered but I got a file "bar" with no extension downloaded. The file of course content the HTML page.
What is happening ?
UPDATE :
I am actually using a router, not direct app.
And I think this 'download' occure only when I try to reach
router.get('/', (res, req) => res.send(fileBar));

How to re-translate image from other website (hiding source URL)

I have a link to the image like
this or that.
I'm trying to re-translate this image from other source URL to some link, f.e http(s)://examplewebsite.com/john.
So, it doesn't need to be a redirect, but rather "showing" image on a different link. I've tried using express.static but it doesn't work.
Thanks in advance
If I understand it right, you have your express server and you want to include foreign images in response while hiding source url
In the simplest form, every time someone requests your page, you would fetch the image you want, encode it in base64 and include this base64 as src for the img
const express = require('express')
const fetch = require('node-fetch')
const app = express()
const port = 3000
app.get('/', (req, res) => {
fetch('https://www.gravatar.com/avatar/fdb4d2674d818861be4a4139469ebe59?s=48&d=identicon&r=PG&f=1')
.then(res => res.buffer())
.then(buffer => {
res.send(`
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p>hello</p>
<img src="data:image\png;base64, ${buffer.toString('base64')}" alt="image">
</body>
</html>
`)
})
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
ideally you would create a separate endpoint for these images and also cache them (in memory or on hard drive) to not re-download them every time you need them

Uncaught SyntaxError: Unexpected token < for JavaScript files

I am developing a MEAN stack CRUD project . After build my project I am getting this error from index.html file in dist/ngAppVideos/index.html folder.i tried <base href="/"> but no luck.
This is my index.html file
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>NgAppVideos</title>
<base href="/ngAppVideos/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="runtime.js"></script>
<script type="text/javascript" src="polyfills.js"></script>
<script type="text/javascript" src="styles.js"></script>
<script type="text/javascript" src="vendor.js"></script>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
This is server.js file
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const api = require('./server/routes/api');
const port = 3000;
const app = express();
api.use(express.static(path.join(__dirname, 'dist')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/api', api);
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/ngAppVideos/index.html'));
});
app.listen(port, function () {
console.log("Server running on localhost:" + port);
});
I tried many ways like modifying base-href location in index.html file but didn't work
in my server.js I changed my __dirname to dist/index.html but this time it just prompt No such directory can be found..error.
Thanks!
you have a few mistakes:
1)for set public file to dist must be set the full path of dist.maybe is there in a subdirectory or anything like this.
2)in your node.js code, you tell return all GET request by an HTML file and in front-end code, you get a javascript file but your server code sends an HTML file and front-end wait for javascript code but get HTML file and send you this error.
to solving these problems must be set a correct public folder and put your javascript file to it and change get javascript path in front, for example
set public like this:
app.use(express.static(path.join(__dirname, 'subdirectory/dist')))
and change script tag to:
<script type="text/javascript" src="/runtime.js"></script>
don't forget put your javascript file in dist folder

Express only serving css file in main page

I am learning node and using expressjs the problem is that the css file is only working on the main page and not any other page following is the code for the app:
var express = require("express");
var app = express();
// assets
app.use(express.static("public"));
// simple file testing
app.get("/anything/:stuff", function(req, res){
var stuff = req.params.stuff;
res.render("love.ejs", {stuff: stuff});
});
// posts page
var books = [
{title:"Harry Potter",author:"JK Rowling",editions:7},
{title:"Peere Kamil",author:"Humaira Saeed",editions:4},
{title:"Mushaf",author:"Abdullah khan",editions:2}
];
app.get("/books", function(req, res){
res.render("books.ejs",{books:books});
});
app.listen(3000, process.env.IP, function(){
console.log("Serving Now!");
});
The following is the code for the page where it is not working.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="app.css" />
<title>demo app</title>
</head>
<body>
<h1>You fell in love with : <%= stuff %> </h1>
<%
if(stuff.toUpperCase() === "WAQAS"){ %>
<P>GOOD CHOICE HE IS THE BEST</p>
<% } %>
<p>P.S This is the love.ejs file</p>
</body>
</html>
The file is under public directory.
Use an absolute URL for the CSS file, so the browser doesn't look for it relative to the current URL:
<link rel="stylesheet" href="/app.css" />
Explanation: say that you open the URL /anything/helloworld in your browser. When your HTML contains just app.css, without the leading slash in front of it, the browser will try and load /anything/app.css (because without that slash it's relative to the current URL), which doesn't point to your CSS file.
When you add the leading slash, express.static will be able to find the CSS file in public/.

Resources