Node.js: stream remote file to file download - javascript

I get back a remote url which contains a pdf file at another domain. I need to pass this file to the user somehow through initiating file download Save As dialogue inside the client's browsers.

var request = require("request");
expressjs_app.get("/file_url", function(req, res){
request.get('remote_file_url').pipe(res);
});
if you are using http module and not express js then replace the 2nd part with:
var http = require("http");
http.createServer(function (req, res) {
if (req.url === '/file_url') {
request.get('remote_file_url').pipe(res);
}
});
Update:
With 'request' module deprecated, there are other alternatives that can be used. Below snippet is using nodejs native https module. Replace the request.get line with this:
var https = require('https');
https.get('remote_file_url', remote_response => remote_response.pipe(res));

Related

Node JS/localhost server is not showing the image

I created localhost/server on node js, and my pictures/img tag doesn't work
<div class="text-center">
<img alt = "Bulb" src="pic_bulboff.gif" class="rounded" alt="bulboff">
</div>
but the problem is that they show up when I open them in a regular browser without the server
const http = require('http')
const fs = require('fs')
const port = 3000
const server = http.createServer(function(req, res){
res.writeHead(200, { 'Content-Type': 'text/html'})
fs.readFile('index.html', function(error, data) {
if(error) {
res.writeHead(404)
res.write('Error: File not Found')
} else {
res.write(data)
}
res.end();
})
})
above is the node server.
is there a problem that I can't really see?
Thanks!!!
By default a nodejs http server does not serve ANY files at all. You've created an http server that serves index.html for ALL incoming requests. So, a browser makes a request from your web server and you send it the HTML content from index.html.
Then, the browser parses that HTML and sees an <img> tag with a src attribute of "pic_bulboff.gif" so the browser then sends a request to your web server asking it for the content for /pick_bulboff.gif. But, you web server just responds to that request by sending index.html. That obviously doesn't work. You need your web server to know the difference between different path requests so it will server index.html when the browser is requesting /, but will serve that image when the browser is requesting /pick_bulboff.gif.
While most people will use a simple web framework that has the serving of static files as a built-in feature (like the Express framework), you can do it manually if you want:
const http = require('http');
const fs = require('fs');
const port = 3000;
function sendFile(fname, contentType) {
res.writeHead(200, { 'Content-Type': contentType});
fs.readFile(fname, function(error, data) {
if(error) {
res.writeHead(404);
res.write('Error: File not Found');
} else {
res.write(data);
}
res.end();
}
}
const server = http.createServer(function(req, res){
if (req.url === "/") {
sendFile('index.html', 'text/html');
} else if (req.url === '/pick_bulboff.gif') {
sendFile('pick_bulboff.gif', 'image/gif');
} else {
res.writeHead(404);
res.end('Error: Unsupported path');
}
});
server.listen(port);
In a more typical implementation, you would put all static files in one directory hierarchy that was separate from your code and you would use functionality similar to express.static() in the Express framework to serve any file in that static files directory that matches an incoming request so you don't have to create a custom route for every single static file you're using in your project.

Node js receive file in HTTP request

I try to create a server, which can receive a file from an HTTP request.
I use Postman as user agent and I add a file to the request. This is the request:
POST /getfile HTTP/1.1
Host: localhost:3000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 9476dbcc-988d-c9bd-0f49-b5a3ceb95b85
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="test.xls"
Content-Type: application/vnd.ms-excel
------WebKitFormBoundary7MA4YWxkTrZu0gW--
But when the request reaches the server I can not find the file in it (I mean in the request).
I tried to receive it from the body part of the request, but it returned > {} <. I tried to figure out, how can I refer to the name of the file, but unfortunately I can not find any reference in the request header for the name of the file...
Can anybody help me to find out, what should I do?
As a follow up to my comment, you can use the multer module achieve the thing that you want:
https://www.npmjs.com/package/multer
const express = require('express');
const multer = require('multer');
const app = express();
const upload = multer();
app.post('/profile', upload.array(), function (req, res, next) {
// req.body contains the text fields
});
var app = require('express')();
var multer = require('multer');
var upload = multer();
app.post('/your_path', upload.array(), function (req, res, next) {
// req.files is array of uploaded files
// req.body will contain the text fields, if there were any
});
You need to parse the form data from the request. There are a few packages that solves this problem, notably formidable, busboy (or busboy-connect), parted and flow.
Here's a solution using formidable, it is my preferred solution for things like image uploads because it saves to disk.
If you just want to read the file, you can use one of the other packages above.
Install formidable
npm install formidable --save
Then, in your server, you will have to parse the data from the client:
// Somewhere at the start of your file
var IncomingForm = require('formidable').IncomingForm
// ...
// Then in your request handler
var form = new IncomingForm()
form.uploadDir = 'uploads'
form.parse(request, function(err, fields, files) {
if (err) {
console.log('some error', err)
} else if (!files.file) {
console.log('no file received')
} else {
var file = files.file
console.log('saved file to', file.path)
console.log('original name', file.name)
console.log('type', file.type)
console.log('size', file.size)
}
})
A few things to note:
formidable saves files with new names, you can use fs to rename or move them
you can set form.keepExtensions = true if you want saved files to keep their extensions

making js and other files available to html via node.js http server

I have a very simple web server like this:
var http = require('http');
var fs = require('fs');
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/html' });
fs.readFile('./index.html', 'utf-8', function (err, content) {
if (err) {
res.end('something went wrong.');
return;
}
res.end(content);
});
}).listen(8080);
console.log("Server running on port 8080.")
This renders my index.html without any issues, but if I try to reference another file in my index.html via a script tag for instance, the site just gets stuck, unable to find the file which exists in the server directory.
How can I make those files available to my index.html file?
Please keep in mind that I realize this can be done much more easily with Express but I do not wish to use Express. I am trying to learn how things work behind the scene. Thanks in advance.
You need to make the directory visible to public. Its is recommend to use framework while developing the Node.js application.
Here is the code below to server file without framework.
var basePath = __dirname;
var http = require('http');
var fs = require('fs');
var path = require('path');
http.createServer(function(req, res) {
var stream = fs.createReadStream(path.join(basePath, req.url));
stream.on('error', function() {
res.writeHead(404);
res.end();
});
stream.pipe(res);
}).listen(9999);
Refer : Node itself can serve static files without express or any other module..?

How to host an app on node server?

I have a simple html file that refers to a CSS stylesheet and a javascript file. I'm supposed to host it on a node server. I Googled the procedure and surmised that I was supposed to include the files like so,
var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');
console.log(index);
var javaScriptFile = require('some/javascript/here');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'html'});
res.end(index);
}).listen(10024);
When I run the code, my HTML is rendered but my file treeStructServer.js is shown as an exact copy of the HTML, which causes an error. Any idea why that's happening? I'm out of my depth.
With your current node script you just return the HTML file on every request, no matter what the URL is. You could instead use the node-static module. Install it by running npm install node-static and then replace your Node code with the following:
var static = require('node-static');
//
// Create a node-static server instance to serve the current folder
//
var file = new static.Server('./');
require('http').createServer(function (request, response) {
request.addListener('end', function () {
//
// Serve files!
//
file.serve(request, response);
}).resume();
}).listen(10024);

Node.js server gives problems with scripts and images

I just started using node js and I've moved one of my websites on it:
var http = require('http');
var fs = require('fs');
var app = http.createServer(function (req, res) {
fs.readFile('./index.html', 'utf-8', function(error, content) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end(content);
});
});
app.listen(8080);
The index.html is my website home page. With only html it works, but if i put tags in it (for including jquery for example), it gives JS errors in firebug : Uncaught syntax error : unexpected token < in jquery.js, and then of course '$ is undefined'.
It doesn't load images either.
I don't really need to do some routing or use Express framework or anything, it's just a simple one-page website.
What am I doing wrong ?
Your server isn't handling requests for images or other resources. All requests are given the same response of the ./index.html page.
This means that if an external script or an image is included in the page, when a request is made by the browser for those resources, the original index.html page will be delivered instead.
NodeJS is fairly low-level. You need to set up your server to manually handle requests for different types of resources based on the URL for each request.
Your best bet will be to read through some NodeJS tutorials. They should cover the basics of serving content, though many of them won't deal with the lower-level details, and will suggest packages like Connect or Express.
Change your code to this, and you'll see all the resources being requested.
var http = require('http');
var fs = require('fs');
var url = require('url');
var path = require('path');
var app = http.createServer(function (req, res) {
var pathname = url.parse(req.url).pathname;
var ext = path.extname(pathname).toLowerCase();
console.log(pathname);
if (ext === ".html") {
fs.readFile('./index.html', 'utf-8', function(error, content) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end(content);
});
}
});
app.listen(8080);

Categories