Node.js - Window.Location.Href Not Working - javascript

I am trying to build a Puppeteer app that can be uploaded to a web server and receive parameters via the URL, but I can't seem find a way to get the current URL from my browser using Node. Right now I have a default server.js file created by Visual Studio which I modified to include code for getting the URL, but when I run the file I get an object promise error for window.location.href.
Here is the codeL
'use strict';
var http = require('http');
var port = process.env.PORT || 1337;
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
var url = window.location.href;
res.end('Hello World\n' + url);
}).listen(port);
My goal is to be able to get the URL and then pass it to my Puppeteer script as a parameter when it is run. The above code should result in a url value of http://localhost:1337 which could then be modified to include any additional parameters by appending query strings.
Next I tried getting the URL outside of the createServer loop by appending the following:
var url = window.location.href;
document.write(url);
That causes the app to crash with no error message beyond failing to connect to the server.
This is my first Node.js application, so the concept of server side javascript is new to me.

Related

Node.js serving a HTML file on a remote network

I'm a Node.js newb, so I'm not sure if it's possible to do what I'm trying to accomplish. Here is my configuration:
I have a Node.js server running on a Raspberry Pi on my home network. I have an HTML file on an external IP. I wish to render React components on this HTML file.
From what I've seen, people have used Node servers to display js on a local HTML file, so the path would normally look like this, assuming the directory is called 'dir':
const express = require('express');
const app = express();
// Static Routes
app.use('/dist', express.static(path.join(__dirname, 'dir')));
// App Route
app.get('/', (req, res, next) => res.sendFile(path.join(__dirname,
'index.html')));
Which, to my knowledge, transfers the HTML file found at the previously specified path. But where is this transferred to? Any way I can specify the path name based on an external IP + user + password, and file path?
Which, to my knowledge, transfers the HTML file found at the previously specified path. But where is this transferred to?
It transfers the file contents from disk to the client's network connection, when they request it (i.e. not when the server starts up).
Any way I can specify the path name based on an external IP + user + password, and file path?
Not with express.static. If you want to make your server serve an external page (proxying), you can do that: https://stackoverflow.com/a/10435819/7011366. Since you'll have access to the url & cookies, you can do whatever you like with the path/user/password.
app.post('/my_url', function(req, res) {
var options = {
host: MY_DOMAIN,
path: '/' + req.query.username,
method: 'GET',
};
var req = http.request(options, function(res) {
// etc...
// send response to client
}).on('error', function(e) {
// handle error...
}).end();
});
This above example makes a request to the external page every on every request. If you don't want that, you can store it in memory and only update it periodically.
let myHtml = "";
let fn = () => {
var options = {
host: MY_DOMAIN,
path: '/' + req.query.username,
method: 'GET',
};
var req = http.request(options, function(res) {
// etc...
// save response to myHtml as string
}).on('error', function(e) {
// handle error...
}).end();
};
setInterval(fn, 60000);
fn();
app.post('/my_url', function(req, res) {
res.end(myHtml);
});
You can not achieve it directly for the files stored on remote machine. Express static path works with local file system only.
Possible way for this could be, fetch file from the remote machine every time you get a new request. But no one does this.

Use Express server to control a nodejs application

I have a node.js application which I use to interact with a REST API provided by another server. I would like to expose a web interface (html + css + javascript) using express.js in order to control the first application.
How can I let the browser talk to the server and let it make node.js actions like using http from that machine or writing to its filesystem? I tried using XMLHttpRequest, but HTTP requests are sent by my local PC instead of from my server.
The only solution I found is using XMLHttpRequest in the javascript of my web interface to invoke some middleware functions on my server, but I had some problems: when I make POST requests, I cannot read data from server. I used FormData and its append method to make the "body" of the POST request, then used body-parser in express to read that body, but it turns out to be always empty. Also tried changing the 'Content-Type' of the header.
Any suggestions? Any better solution than mine (I think it is not efficient)?
As pointed by Jonas, using node server as proxy would be the right approach.
I'm providing sample code for both frontend as well as backend app. Hope this helps you.
Frontend App Code
<html>
<head>
<script type="text/javascript">
function sendData(data) {
if (!data) {
// lets define some dummy data for testing
data = { somekey: "somevalue", anotherkey: "anothervalues" };
}
var XHR = new XMLHttpRequest();
var FD = new FormData();
// Push our data into our FormData object
for (name in data) {
FD.append(name, data[name]);
}
// Define what happens on successful data submission
XHR.addEventListener("load", function(event) {
alert("Yeah! Data sent and response loaded.");
alert(event.target.responseText);
});
// Define what happens in case of error
XHR.addEventListener("error", function(event) {
alert("Oops! Something went wrong.");
});
// Set up our request
XHR.open("POST", "http://path/to/your/nodejs/server/app");
// Send our FormData object; HTTP headers are set automatically
XHR.send(FD);
}
</script>
</head>
<body>
<button onclick="sendData()">Send Test Request to the Server</button>
</body>
</html>
Backend App code
const http = require('http');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', (req, res) => res.send('Yeah! Server is UP! Post some data'));
app.post('/', (req, res) => {
// You'll see the posted data in req.body, simply for testing purpose return it back to the calling user
res.json(req.body || {});
});
const server = http.createServer(app);
server.listen(3000);
server.on('error', console.error);
server.on('listening', () => console.log('Listening on 3000'));
process.on('exit', (code) => console.warn('Server terminated with code=' + code));
Please note that for this backend app to run, you must have installed following npm packages: express, body-parser

node.js internal message server

I am pretty new to node.js. I am working on an app able to display NFC content on a webpage. I am using nfc-pcsp package (https://github.com/pokusew/nfc-pcsc), I can easily read data on server side. Now I just would like to display the data in the webpage, but I am stuck on the logic. Here is a part of my server code:
// ### launch server for client
var http = require('http');
var html = require('fs').readFileSync(__dirname+'/custom.html');
var server = require('http').createServer(function(req, res){
res.end(html);
});
server.listen(3000, '127.0.0.1');
console.log('Server running at http://127.0.0.1:3000/');
//######
//#launch NFC routine ######
const nfc = new NFC(); // const nfc = new NFC(minilogger); // optionally you can pass logger to see internal debug logs
let readers = [];
nfc.on('reader', async reader => {
pretty.info(`device attached`, { reader: reader.name });
// the event is correctly displayed in the console. How to update html here?
readers.push(reader);
nfc.on('error', err => {
pretty.error(`an error occurred`, err);
});
It seems to me that I need a res object to update the html page, but as I do not get any request from client, how do I update the page just based on the callback from NFC module reader? Hope my question is clear.
Thanks,
Matt
I suggest you to use the express API
command with npm CLI : npm install --save express at your root project folder in your terminal
Then, you will be able to create a route in Get, Post, Put or Delete.
Next, In your client side you will be able to call this route by a get, post or whatever with a promise, ajax request whatever you want :)
Just understand that in order to receive or send data to your server, you need an url and with Express, you can create your own url.
https://www.npmjs.com/package/express
Don't hesitate to have a look on this API, and i'm pretty sure you will find the answer to your question on your own :)

reading request object in node.js from localhost

I'm new to node.js and I'm trying out a few easy examples using localhost:XXXX.
I want to read my request object from node. I have a book and in the book they use cURL(some program) to comunicate with node instead of the browser. Is it possible to write something in the browser adress field and send it to localhost and have a request object sent to node that looks exactly like if I had a typed in a url to a server somewhere? OIf so, how do I write? Do I have to use cURL or something like it if i use localhost?
I'm very new to node and javascript so I dont't know if I'm using the right words. I have tried to search but I dont't think I know the right terms to search for.
This is my server code:
var port = 3000;
http.createServer(function (req, res) {
var url = parse(req.url);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n' + url );
}).listen(port);
When i write http://localhost:3000/hello.com in the address field i was hoping i would get Hello world hello.com in the browser but i get hello world [object object]
Please help.
You can use your regular browser by testing it. In your URL address enter URL address that you have in your cURL address. For instance:
localhost:3000/index.html
If you would like to have more sophisticated tool that gives you more information about request/response you can use tool like Postman for that
In your code use:
res.end('Hello World\n' + url.parse(req.url, true));
url is an object, you need to specify property or method that you are calling on it.
Here is an example on how to parse URL. Easy URL Parsing With Isomorphic JavaScript:
Above answer given by #Vlad Beden looks good but you may want to play with following code
var http = require("http");
var port = 3000;
http.createServer(function (req, res) {
console.log('Requested method: ', req.method);
var params = parseUrl(req.url);
res.writeHead(200, { 'Content-Type': 'text/plain' });
var data = 'Hello World'
for(var i=0; i<params.length; i++)
data += '\n'+params[i]
res.end(data);
}).listen(port);
var parseUrl = function(url) {
var params = [];
if(url && url != '' && url != '/') {
url = url.replace(/^\/|\/$/g, '');
params = url.split('/');
}
return params;
}
You may try http://localhost:3000/hello.com or http://localhost:3000/hello.com/google.com/more.com/etc . I would like to recommend you print request object console.log(req) and have a look to understand url, method, headers, etc.

Express hanging in Chrome post AJAX delete

When issuing a same-origin AJAX delete via jQuery, subsequent calls to the server via the same client are hanging. I've excerpted the problem below. Please advise if something is malformed as this would seem like such a strange bug.
Using Express 3.5.1, jQuery 1.11.0, and Chrome 33.x.
To replicate:
Create directory with code below and install Express dependency
node main.js
Visit localhost:5000 in Chrome 33
Click on simulated deletion link
Wait for a moment, and refresh
In the Network region, Chrome will handle the DELETE request ok, but the subsequent server call will stay as "pending". I have tried both HTML and JSON dataTypes and responses.
main.js:
// Dependencies
var http = require('http'),
express = require('express');
// Basic app
var app = express();
// Logging (for debugging), and parsing dependencies
app.use(express.logger());
app.use(express.json());
app.use(express.urlencoded());
app.use(express.cookieParser());
app.use(express.methodOverride());
// Simple home page
app.get("/", function(req, res) {
var head = "<head><script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js'></script></head>",
body = "<a id='link' style='text-decoration:underline;cursor:pointer;'>Click here to simulate delete</a>, wait a second, then try refreshing.",
params = {
url : "/item/5",
type : "DELETE"
}
ajax = "<script>$(function() { $('#link').click(function() { $.ajax(" + JSON.stringify(params) + "); }); });</script>"
res.send("<html>" + head + "<body>" + body + ajax + "</body></html>");
});
// Simulated deletion
app.del("/item/:id", function(req, res) {
res.send(204);
});
// Make the server listen
var server = http.createServer(app).listen(5000);
This ended up being a non-node-related third-party plugin (I believe it was Sophos, but I may be mistaken). Once the plugin was disabled, everything worked fine.
You can see more information here: https://github.com/strongloop/express/issues/2069

Categories