I am trying to learn the ins and outs of node. I know you can serve a file with a framework but I am trying to do it manually. I have a jpeg file in './public/logo.jpg'. When I send the request through localhost:8080 I don't get the image, just a blank screen with a generic image placeholder. What am I doing wrong? Thanks!
var http=require('http');
var url=require('url');
var fs=require('fs');
// creates a new httpServer instance
http.createServer(function (req, res) {
// this is the callback, or request handler for the httpServer
log('in server callback')
res.ins=res.write;
var parse=url.parse(req.url,true);
var path0=parse.pathname;
console.log(path0)
// respond to the browser, write some headers so the
// browser knows what type of content we are sending
var serveFile=function(){
var path='./public'+path0
fs.exists(path,function(e){
if(e){
log('serving file')
log(path)
fs.readFile(path,'binary',function(err,data){
if(data){
res.writeHead(200, {'Content-Type': 'image/jpeg'});
res.ins(data)
res.end()
}
})
}
else{
log('no file to serve')
log(path)
servePage()
}
})
}
serveFile()
}).listen(8080); // the server will listen on port 8080
Simply change the following two lines in your readFile callback :
res.writeHead(200, {'Content-Type': 'image/jpeg'});
res.write(data, 'binary');
Use response.write to send data to the client and set encoding to binary. (Default is utf-8)
Related
I have a webpage with an HTML, CSS, and JS file. It also has one image. I am able to get all of them to function and serve onto the client side, except for the javascript portion. It is most likely a silly syntax thing but I have not been able to solve it.
Here is the code for my .js serving:
else if(req.url === '/index.js'){
console.log("SERVING JS")
res.writeHead(200, {'Content-Type': 'application/json'})
var javaContents = fs.readFileSync('./public/index.js', {encoding: 'UTF8'});
res.write(javaContents);
res.end();
}
^^^ Which is inside my requestHandler function:
function requestHandler(req, res){
}
Before this, I also have:
var http = require('http'), fs = require('fs');
var fs = require('fs');
And I declare my server variable last:
var server = http.createServer(requestHandler);
server.listen(9934, function(){
console.log("== Server is listening on port 9934");
});
I could post all my code but I think that is not necessary. Thank you!
I am new to nodeJS. I am trying to load an index.html page onto my 8080 port and have this:
var http = require('http');
var fs = require('fs');
var PORT = 8080;
function home(req, res) {
if(req.url == '/'){
fs.readFile('index.html', function read (err, data) {
res.writeHead(200, {'Content-type' : 'text/html'});
res.write(data);
res.end();
});
}
};
var server = http.createServer(function (req, res) {
home(req, res);
});
server.listen(PORT);
I have 3 files in the same directory: index.html, style.css, server.js. I start up the server and the page will not load until after I hit cntrl + c. Why is this?
You have written the data to the response, but you have not finished the response. Put res.end(); after your res.write function.
Without this, the browser keeps waiting for more data from the server. When you shut down the server with Ctrl-C, the server closes the connection, and the browser renders what it received.
If you are new to Node, I would recommend looking into something like Express, which handles a lot of important things like routing (what URLs go to which pages) for you and will save you a lot more if statements in the future.
I have server.js and client.html.
Server.js is running on nodejs and is simply:
var http = require('http'), fs = require('fs');
var app = http.createServer(function(request, response) {
fs.readFile("client.html", 'utf-8', function(error, data) {
response.writeHead(200, {'Content-Type': 'text/html'});
response.write(data);
response.end();
});
}).listen(80);
and then I have client.html which is also very simply just
<img src="/public/images/avatar.gif">
Which just displays as though the image is not valid, I have checked the the director over and over and it is fine, why would it be doing this? I thought it might be because of the headers but text/html should surely display images?
Regards
Matt
It's not displaying the image because for every request (including the image request) it's returning the contents of clients.html.
If you want a static file server, i suggest looking at connect: http://www.senchalabs.org/connect/ or for something simpler, have a look at this: https://gist.github.com/rpflorence/701407
I'm trying to create a Node server that generates a PDF on-the-fly using PDFKit. The PDF is generated based on parameters from a POST request (via Express). One of the parameters specifies an image URL, which the server downloads and injects into the PDF.
Right now, I have the following structure:
// Get dependencies
var express = require('express'),
http = require('http'),
fs = require('fs'),
pdfDocument = require('pdfkit');
// Get express started.
var app = express();
// Use JSON in POST body
app.use(express.json());
// Setup POST response
app.post('/post_pdf', function(req, res) {
// Get the PDF initialized
var doc = new pdfDocument();
// Set some headers
res.statusCode = 200;
res.setHeader('Content-type', 'application/pdf');
res.setHeader('Access-Control-Allow-Origin', '*');
// Header to force download
res.setHeader('Content-disposition', 'attachment; filename=Untitled.pdf');
// Pipe generated PDF into response
doc.pipe(res);
/**
* Generate PDF contents
*/
// Prepare write stream for image
var image = fs.createWriteStream('image.jpeg');
// Download image
http.get("http://dummyimage.com/640.jpeg", function(response) {
// Pipe response into image write stream
// (because PDFKit needs to read from a saved file)
response.pipe(image).on('close', function() {
// Read data back, make sure there are no errors
fs.readFile('image.jpeg', function(err, data) {
if (err) throw err;
/**
* Use `data` to get image info (width, height, etc.)
* ------------------
* Inject image
*/
// Close document and response
doc.end();
res.end();
return;
})
});
});
});
I have two questions:
Is there a less messy way to do this, perhaps with fewer nested callbacks? I'm totally open to adding another dependency to make life easier.
Right now, the code above does not work. It returns a PDF, but the PDF is corrupted (according to Preview). Any tips as to why this could be occurring are very welcome.
In debugging this issue, I discovered several things:
PDFKit does not need to read info from a file. It will also accept a Buffer
doc.image(myBuffer); // You don't have to use a path string
When piping a file directly into the response, a manual call to response.end() will cause problems if the file has already been closed
doc.pipe(res); // Pipe document directly into the response
doc.end(); // When called, this ends the file and the response
// res.end(); <-- DON'T call res.end()
// The response was already closed by doc.end()
return;
Request is a super-useful NodeJS library that can flatten the callback tree
Updated code:
var express = require('express'),
request = require('request'),
pdfDocument = require('pdfkit');
// Start Express
var app = express();
// Use JSON in POST body
app.use(express.json());
// Setup POST response
app.post('/post_pdf', function(req, res) {
// Create PDF
var doc = new pdfDocument();
// Write headers
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Access-Control-Allow-Origin': '*',
'Content-Disposition': 'attachment; filename=Untitled.pdf'
});
// Pipe generated PDF into response
doc.pipe(res);
// Process image
request({
url: 'http://dummyimage.com/640.jpeg',
encoding: null // Prevents Request from converting response to string
}, function(err, response, body) {
if (err) throw err;
// Inject image
doc.image(body); // `body` is a Buffer because we told Request
// to not make it a string
doc.end(); // Close document and, by extension, response
return;
});
});
const fetch = require('node-fetch');
const PDFDocument = require('pdfkit');
const doc = new PDFDocument({});
url = AnyImageUrl;
res = await fetch(url,{encoding: null });
imageBuffer = await res.buffer();
img = new Buffer(imageBuffer, 'base64');
doc.image(img,(doc.page.width - 525) /2, doc.y, {align: 'center', width: 125});
I just setup a basic node.js server with socket.io on my local machine. Is there a way to set a document root so that you can include other files. Ie. Below I have a DIV with a a background image. The path the image is relative to the location of the server, however this is not working. Any ideas? Thanks!
var http = require('http'),
io = require('socket.io'), // for npm, otherwise use require('./path/to/socket.io')
server = http.createServer(function(req, res){
// your normal server code
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('<div style="background-image:url(img/carbon_fibre.gif);"><h1>Hello world</h1></div>');
});
server.listen(8080);
// socket.io
var socket = io.listen(server);
Use Express or Connect. Examples: https://github.com/spadin/simple-express-static-server, http://senchalabs.github.com/connect/middleware-static.html
For the background-image style, browser will create a entirely new HTTP Request to your server with path *img/carbon_fibre.gif*, and this request will certainly hit your anonymous function, but your response function only write back a div with ContentType: text/html regardless the req.pathname so that the image cannot be properly displayed.
You may add some code to your function like:
var http = require('http'),
io = require('socket.io'),
fs = require('fs'),
server = http.createServer(function(req, res){
// find static image file
if (/\.gif$/.test(req.pathname)) {
fs.read(req.pathname, function(err, data) {
res.writeHead(200, { 'Content-Type': 'image/gif' });
res.end(data);
});
}
else {
// write your div
}
});
server.listen(8080);
I'm not very familiar with nodejs, so the code above only demonstrates a logic but not the actual runnable code block.