Image Successfully Downloads From Node Server But Does Not Display - javascript

I have a folder on my node server called /pictures/renamed. In it, I'm trying to save an image and it does successfully save it however it doesn't display anything except a message that says "It appears that we don't support this file format". I changed the image extension to jpeg, jpg and png but the image still doesnt display. Why is this happening?
const express = require('express');
const bodyParser = require('body-parser')
const app = express();
const https = require('https');
const fs = require('fs');
const cors = require('cors');
const pathh = require('path')
//Setting up the cors config
app.use(cors());
//BodyParser middleware
app.use(express.json());
function download(){
const url = 'https://unsplash.com/photos/3aqiY4t1qxM/download?ixid=MnwxMjA3fDB8MXxhbGx8Mnx8fHx8fDJ8fDE2NTY3Njg2Mzc&force=true'
const path = pathh.resolve("./pictures/renamed/", 'imageWorld.jpg')
const fileStream = fs.createWriteStream(path)
https.get(url,(res)=>{
res.pipe(fileStream)
fileStream.on('finish',()=>{
fileStream.close()
})
})
}
download();
//Serve static files if in production
if(process.env.NODE_ENV === 'production'){
//Set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) =>{
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'))
});
}
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));

That's because the response is an html document (telling you that you are redirected) rather than actual jpg data. It looks something like this in a text editor:
<html><body>You are being redirected.</body></html>So, what you saved was not a valid photo file.
Referring to https://github.com/follow-redirects/follow-redirects, I ran npm install follow-redirects then replaced const https = require('https') with const { https } = require('follow-redirects') in the js file, and then I could get the jpg.

Related

Image not displayed in browser after being uploaded with node

I am trying to upload some pics using a node-express server and I am facing two issues, one is regarding the picture extension and the other one regarding the picture itself being displayed.
So after I am uploading the file is added into the upload path but a kind like this auto-generated name 2f22c2502b907f7bf0bc2567c43c801cwithout extension like .png and even if I'm renaming the file like 2f22c2502b907f7bf0bc2567c43c801c.png in browser is looking like default empty icon browser instead of uploaded picture.
How can I solve those two issues ?
const express = require('express')
const multer = require('multer')
const path = require('path')
const child_process = require("child_process");
const app = express();
const PORT = 3000;
const upload = multer({ dest: 'uploads/' })
app.post('/upload', upload.single('picture'), function (req, res, next) {
const FILE_OUTPUT = path.join(__dirname, `uploads/${req.file.path}`)
child_process.execFile(
"/usr/bin/convert",
[path.join(__dirname, req.file.path), "-resize", "280x150", FILE_OUTPUT],
function() {
console.log('done resizing', FILE_OUTPUT)
return res.send(`
<img src="${FILE_OUTPUT}"/>
`);
}
);
});
app.use('/', express.static(path.join(__dirname, 'public')));
app.listen(PORT, function () { console.log('Example app listening on port: ', PORT) })
That should be a multer task because multer will not append the file extension so what need to be done is a bit of setup on multer.
Check this response multer setup

Socket.io Page Loading Forever

Note - I'm using Pug to render my pages.
My page, when including the script(src="/socket.io/socket.io.js"), does not stop loading.
Here's the relevant content from my app.js.
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
All packages are installed correctly.
In my head tag:
script(src="/socket.io/socket.io.js")
script.
var socket = io();
Yet, my page does not stop loading. What have I done wrong here?
Update:
app.js
const path = require('path');
const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const AppError = require('./utils/appError');
const globalErrorHandler = require('./controllers/errorController');
const userRouter = require('./routes/userRoutes');
const viewRouter = require('./routes/viewRoutes');
const projectRouter = require('./routes/projectRoutes');
const app = express();
app.set('view engine', 'pug')
app.set('views', path.join(__dirname, 'views'));
//MIDDLEWARES
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'));
}
app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use((req, res, next) => {
req.requestTime = new Date().toISOString();
next();
});
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'overview'));
})
//ROUTES
app.use('/', viewRouter);
app.use('/api/1/users', userRouter);
app.use('/api/1/projects', projectRouter)
app.all('*', (req, res, next) => {
next(new AppError(`Can't find ${req.originalUrl}.`, 404));
});
app.use(globalErrorHandler);
module.exports = app;
server.js (run by node)
const mongoose = require('mongoose');
const dotenv = require('dotenv');
// mongoose.set('debug',true);
dotenv.config({path: './config.env'})
const app = require('./app');
const DB = process.env.DB.replace('<PASSWORD>', process.env.DBPASS);
mongoose.connect(DB, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true
}).then(con => {console.log('🔗 Connected.')})
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`📈 Running on ${port}.`)
});
const http = require('http').Server(app);
const io = require('socket.io')(http);
io.on('connection', socket => {
socket.on('greeting', msg => {
console.log(msg);
})
});
http.listen(80);
Now that you've shown your code, this part is wrong:
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`📈 Running on ${port}.`)
});
const http = require('http').Server(app);
const io = require('socket.io')(http);
You are creating two separate servers there and binding socket.io to the one that isn't running. Change that above code to this:
const port = process.env.PORT || 3000;
const server = app.listen(port, () => {
console.log(`📈 Running on ${port}.`)
});
const io = require('socket.io')(server);
Earlier attempt to help before OP had shown their actual code.
My guess is that something is messed up in your environment or something is wedged in your OS or something is blocking some requests. To rule things in or out, I would suggest you try this simple app which works just fine for me:
// app.js
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const path = require('path');
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "temp.html"));
});
io.on('connection', socket => {
socket.on("greeting", msg => {
console.log(msg);
});
});
server.listen(80);
and the HTML file temp.html:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="/socket.io/socket.io.js"></script>
<style>
</style>
</head>
<body>
<button id="myButton">Press Me</button>
<script>
const socket = io();
document.getElementById("myButton").addEventListener("click", () => {
socket.emit("greeting", "hi from client");
});
</script>
</body>
</html>
You put these two files in the same project and you have the server-side socket.io library installed in that project (it should be in node_modules per a normal installation).
Start the server with node app.js in a way that has a server console that you can see output from. Then, from a browser on the same computer, go to http://localhost. It should load a web page with a single button on it. Press that button. You should see a message in the server console that says hi from client each time you press that button.
If this is working, then we would need to see all your project code to see what's wrong with your actual project.
If this isn't working, then we need to know what errors you get. You can try moving this project to a different port in case you have something blocking some things on a particular port. You can reboot your computer in case something in the networking or file system is wedged.

String interpolation on static files served by Nodejs

Hi I have Nodejs server which serves static resource at /assets/meta-info.json which contains:
{
"environmentName": "${ENV_NAME}"
}
The problem is: How to replace ${ENV_NAME} with corresponding system environment variable?
You can probably save it as /assets/meta-info.js
You can import 'dotenv' npm library.
In assets/meta-info.js
require('dotenv').config();
module.exports = {
"environmentName": process.env.ENV_NAME
}
Have a .env file (no extension). have line below:
ENV_NAME=prod
You could modify the file when the server starts and request that modified file (or you can rename the original file and keep serve original modified file)
something like modifying the original file during runtime (which is not advisable as you will modifying the same file again and again) =>
const fs = require('fs');
const path = require('path');
const express = require('express');
const app = express();
app.get('/', (req, res) => {
let fileBuffer = fs.readFileSync('./manifest.json', 'utf-8');
fileBuffer = fileBuffer.replace('${ENV_NAME}', process.env.NODE_ENV);
fs.writeFileSync('./temp.json', fileBuffer);
res.sendFile(path.join(__dirname, './temp.json'));
});
app.listen(4000, () => {
console.log('listening and working');
});
Instead modify it once and send the modified copy.
let fileBuffer = fs.readFileSync('./manifest.json', 'utf-8');
fileBuffer = fileBuffer.replace('${ENV_NAME}', process.env.NODE_ENV);
fs.writeFileSync('./temp.json', fileBuffer);
const app = express();
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, './temp.json'));
});
Now if you are using something like express.serveStatic, then I would create a backup copy of file and modify the original file in place.

how to serve a directory with express?

I would like to create a simple express server that sends a directory like the image following:
Browser directory picture
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'shaders')));
app.use('*', (req, res) => {
res.sendFile((path.join(__dirname, 'shaders')));
});
const PORT = 3000;
app.listen(PORT, () => {
console.log('listening on port ', PORT);
});
This code displays Cannot GET / in the browser window.
Using a library
There are libraries that already do this for you, for example serve-index.
Doing it yourself
This is a modified version of your code to show file content or list the files/directories in a directory. I've added some comments to explain what's happening, but feel free to ask more questions if something is not clear.
const express = require("express");
const path = require("path");
const fs = require("fs");
const app = express();
const listingPath = path.join(__dirname, "shaders");
app.get("*", (req, res) => {
// Build the path of the file using the URL pathname of the request.
const filePath = path.join(listingPath, req.path);
// If the path does not exist, return a 404.
if (!fs.existsSync(filePath)) {
return res.status(404).end();
}
// Check if the existing item is a directory or a file.
if (fs.statSync(filePath).isDirectory()) {
const filesInDir = fs.readdirSync(filePath);
// If the item is a directory: show all the items inside that directory.
return res.send(filesInDir);
} else {
const fileContent = fs.readFileSync(filePath, 'utf8');
// If the item is a file: show the content of that file.
return res.send(fileContent);
}
});
const PORT = 3000;
app.listen(PORT, () => {
console.log("listening on port ", PORT);
});
You can use this as a base to make a template that includes links to the files/directories, to include a link to the parent directory, to show more meta data ...
You can use a static folder for sharing or fetch files via GET request.
app.use(express.static(path.join(__dirname, 'shaders')));
This code displays Cannot GET / in the browser window.
Sending a GET to / will fallback to your app.use * as you don't have a route defined. It's not clear what this should do as you're returning a directory instead of a file, which isn't going to work.
If you'd like to access a specific file, you need to request it directly as localhost:3000/shaders/xxx, etc. The use of express.static appears to be correct.

Get method not able to be detected by the Node.js

I am new to node and express js.Today I am learning and I have initialized node server as:
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const PORT = 3000
const api=require('./routes/api')
const app = express()
app.use(bodyParser.json())
app.use(cors())
api.use('/api',api)
app.get('/', function(req, res) {
res.send('Hello from server')
})
app.listen(PORT, function(){
console.log("Server running on localhost:" + PORT)
});
I have created a folder routes inside server folder and there is api.js file which has GET method to test, whether the api is working or not.Inside api.js I have,
const express = require('express')
const router=express.Router()
router.get('/', (req, res) => {
res.send('from Api Route');
})
module.exports=router
I type node server and it is displaying me :
Server running on localhost:3000
But,when I try to get the url: http://localhost:3000/api,it is displaying me:
And,in api.js file in the arrow function sublime is showing me error in red marker as:
Replace api.use('/api',api) with app.use('/api',api)

Categories

Resources