Can node.js request php file as its endpoint on the same file system, not an http request? - node.js

I am new to node.js and am building a chat appication that is running inside an existing PHP application. I am using expressjs and also postman-request module. I can easily hit absolute urls but when I try to request a file that lives on my own file system, it fails. I have watch tutorials and read the docs and it seems like the only examples ever shown are how to hit external urls.. I can't imagine that it is not possible to hit files that reside on your own file system.
Here is code below: (in my main index.js server file)
const request = require('postman-request');
const url = 'utils/config.php'; // this file merely echos out a json encoded string.
request(url, function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response
console.log('body:', body);
});
Here is the error message:
error: Error: Invalid URI "utils/config.php"
This is the file structure:
-node_modules
-public
-src
-utils
-config.php
index.js (start for node.js - inside src folder)
Any help would be appreciated.

Requesting refers to requesting a file from a webserver. Here, you're trying to request a file path, while the computer thinks is a non-existent URL. The PHP file is just text. It doesn't mean anything to the computer, and the PHP interpreter is what runs the PHP code. You aren't running a PHP server in this case, and you're requesting a file path, not a URL.
You have to start a PHP server first, using the php command. Make sure to pass in the URL (for example, localhost:8080/config.php), and not the file path.
If you wanted to do it entirely from the Node script, you could start a server, request the URL, and then stop the server. It would be possible to use the spawn function from the built-in child_process module (refer here). You could also use exec, but this is probably unnecessarily harder.

Related

Why I am not able to access my index html file when using npm scripts to initiate server?

I am using static middleware function to access HTML file with my express HTTP server. It works fine when I deliberately run the server.js file through node.js command line runnning in the same directory. However after using npm scripts it's not able to locate my assets whether its a HTML or any other media files.
Let me know what you think on these screenshots attached-
<https://i.stack.imgur.com/NxsfW.png>
<https://i.stack.imgur.com/xjbsx.png>
<https://i.stack.imgur.com/O2au5.png>
<https://i.stack.imgur.com/w8zIj.png>
<https://i.stack.imgur.com/po4vY.png>
<https://i.stack.imgur.com/hmB8A.png>

Receiving "error: no such file or directory, open" when passing a remote file to libreoffice-convert library in a Node.js app

I'm currently building a Node.js application that will eventually be used to convert certain file formats into other formats. Most of the work is being done by the libreoffice-convert library.
I am able to do file conversions without any issues when passing a local file path to the library but it doesn't seem to be working when I grab the contents of a remote file via request() and pass the received body to libreoffice-convert.
This is the relevant code I have right now:
request(fileUrl, {encoding: 'binary'}, function(error, response, body) {
const ext = '.html';
libre.convert(body, ext, undefined, (err, done) => {
if (err) {
console.log(`Error converting file: ${err}`);
res.sendStatus(500);
} else {
console.log(done);
}
});
});
I can see that when I run this, libreoffice starts the conversion but eventually, I'm getting this error:
Error: ENOENT: no such file or directory, open '/var/folders/j9/z_z85kh5501dbslrg53mpjsw0000gn/T/libreofficeConvert_-6529-x08o2o3peLMh/source..html
The example libreoffice-convert code gets the local file using fs.readFileSync() but given that I want to get my contents from a remote file, I'm passing the body received in the request() call.
To be sure that body has the correct contents, I compared the result I receive from fs.readFileSync() to the result I receive from request() when calling for the same exact file locally and remotely. There didn't seem to be any differences at all.
Am I missing something or it's a matter that the libreoffice-convert library or libreoffice itself doesn't support this?
libreoffice-convert is dependent on some linux package, i.e. libreoffice-writer. apt install libreoffice-writer will solve your problem.

Relative path not detected in node.js

I got a http server setup using node.js which responds with an html file in port 3000.This html file has a script tag that returns files using relative path.
Eg html file:
<script src="../helloworld.js"></script>
Now the request.url in node.js http server callback returns only /helloworld.js instead of ../helloworld.js
Node.js file:
var http=require('http');
var fs=require('fs')
http.createServer(function(req,res){
if(req.url=='/')
// read and return html file
else
{
console.log(req.url) // prints /helloworld.js instead of ../helloworld.js
//reading helloworld.js from filesystem
}
}).listen(3000)
From the server side, if the url is rooted, ../ means nothing.
That is:
on the url
www.example.com/notroot
Using
../somefile.js
fetches it from
www.example.com/somefile.js
But if the url is already rooted, ie:
www.example.com
using
../somefile.js
will not work, since there is no parent directory to access.
Also, you don't need the fs component to fetch files from the client side. This is only used to fetch files from the server side (where ../ WILL work).
But as you used I assume that this is a DOM tag embedded in the client's browser and not on the server side.

why I can't sendFile() in node.js express when deployed to AWS?

I am using node.js express to serve some static file like svg and json to the client, so I used sendFile() to send the files directly.
so here is my server file structures,
/root // the root of the server
/maps // put some static files
/routes/api // put the web API
in the web API
app.get('/buildings/map',function(req,res){
var mappath = 'maps/ARM-MAP_Base.svg';
res.sendfile(mappath);
})
It works perfectly on my local server to send files to the client, so it means the server could locate the file and send it. but when the server is deployed to the AWS, this methods would encounter a error - 242:Error: ENOENT, stat node.js, looks like it can't open the file in that path
I read some solutions like combining the __dirname with mappath, it didn't work since it would bring to the path of /routes/api/maps/...
so far I have no idea why it works on my local computer but fail to work on the AWS
Relative fs paths like mappath will be resolved from the current working directory, which isn't guaranteed to be consistent. It works locally because you're executing your application with /root as your working directory.
This is why you're finding recommendations to use __dirname, which an be used to resolve paths relative to the current script.
Though, along with it, you'll want to use ../ to resolve parent directories.
var mappath = 'maps/ARM-MAP_Base.svg';
res.sendfile(__dirname + '/../../../' + mappath);
This assumes the current script is located in and __dirname would be /root/maps/routes/api as the indentation in your directory tree suggests.

display html page with node.js

This is my first time with node.js. I get it to display the index.html, but it doesn't display the images on the site or anything else, it ONLY shows the basic html stuff. Here's how I set it up.
There's no apache, php or anything else on the server, just ubuntu, proftp and node(and curl and the other dependencies). I made the main directory for the node files /var/nodeFiles and the directory for the html/site files is /var/nodeFiles/www
so for my node server file I did it like this:
var http = require('http'),
fs = require('fs');
fs.readFile('/var/nodeFiles/www/index.html', function (err, html) {
if (err) {
throw err;
}
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
}).listen(80);
});
this works, but it ONLY shows the index.html file and NOTHING attached to it, so no images, no effects or anything that the html file should display. The files and directories are all correct, I've double checked and the permissions of the folders are correct. So what else do I have to do to get node to display the rest of the site?
I hope I've explained my self correctly, I was told this is the place to ask development questions.
Thank you for taking the time to read this.
but it ONLY shows the index.html file and NOTHING attached to it, so no images,
no effects or anything that the html file should display.
That's because in your program that's the only thing that you return to the browser regardless of what the request looks like.
You can take a look at a more complete example that will return the correct files for the most common web pages (HTML, JPG, CSS, JS) in here https://gist.github.com/hectorcorrea/2573391
Also, take a look at this blog post that I wrote on how to get started with node. I think it might clarify a few things for you: http://hectorcorrea.com/blog/introduction-to-node-js
Check this basic code to setup html server. its work for me.
var http = require('http'),
fs = require('fs');
fs.readFile('./index.html', function (err, html) {
if (err) {
throw err;
}
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
}).listen(8000);
});
This did the trick for me:
var express = require('express'),
app = express();
app.use('/', express.static(__dirname + '/'));
app.listen(8080);
If your goal is to simply display some static files you can use the Connect package. I have had some success (I'm still pretty new to NodeJS myself), using it and the twitter bootstrap API in combination.
at the command line
:\> cd <path you wish your server to reside>
:\> npm install connect
Then in a file (I named) Server.js
var connect = require('connect'),
http = require('http');
connect()
.use(connect.static('<pathyouwishtoserve>'))
.use(connect.directory('<pathyouwishtoserve>'))
.listen(8080);
Finally
:\>node Server.js
Caveats:
If you don't want to display the directory contents, exclude the .use(connect.directory line.
So I created a folder called "server" placed index.html in the folder and the bootstrap API in the same folder. Then when you access the computers IP:8080 it's automagically going to use the index.html file.
If you want to use port 80 (so just going to http://, and you don't have to type in :8080 or some other port). you'll need to start node with sudo, I'm not sure of the security implications but if you're just using it for an internal network, I don't personally think it's a big deal. Exposing to the outside world is another story.
Update 1/28/2014:
I haven't had to do the following on my latest versions of things, so try it out like above first, if it doesn't work (and you read the errors complaining it can't find nodejs), go ahead and possibly try the below.
End Update
Additionally when running in ubuntu I ran into a problem using nodejs as the name (with NPM), if you're having this problem, I recommend using an alias or something to "rename" nodejs to node.
Commands I used (for better or worse):
Create a new file called node
:\>gedit /usr/local/bin/node
#!/bin/bash
exec /nodejs "$#"
sudo chmod -x /usr/local/bin/node
That ought to make
node Server.js
work just fine
You can simply use
res.senFile('PATH_TO_FILE');

Resources