Connect client to Node.js server with HTTP(S) - javascript

Users 'gather' data on their local pc, and they need to be able to upload it to the server.
I setup a simple node.js server like this:
var https = require('https');
var fs = require('fs');
var path = require('path');
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
var server = https.createServer(options, function (request, response) {
response.writeHead(200, {'Content-Type': 'text/bold'});
response.end("Server is running");
});
Now I want to connect a client to it, using a httprequest. I tried JQuery/XMLhttpRequest but I get Cross-origin resource sharing errors (which I get why but I think I don't really want to disable this protection). I think it's possible to use sockets to establish the connection but I'm not sure if that would be a good choice. I'd rather want to work with HTTP requests.
var xmlhttp, text;
xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://localhost/file.txt', true);
xmlhttp.send();
//JQuery get
$.get("http://127.0.0.1:1337")
Anything missing? Feel free to ask.

Change http:// to https:// in your second set of code. Same-origin includes scheme/protocol. (And your server code appears to only be spinning up an https listener anyway. :) ).

Just a hint : If your client application page which is taking to your server is not rendered from the same domain where your server component is running then you will get such errors. This error means your page is going to access resources from another server, not from the server it is originated. All the browsers have such restriction. You can configure on you server to allow access form other domains (domain where your client app is hosted) or host both client app and server from same domain.

Related

How to downgrade socket.io websocket to WS from WSS?

I am making a website that accesses the devices sensors and sends them via socket.io to my local machine.
I can't access the device sensors without HTTPS, so I have to use HTTPS for the website, which is why I uploaded my site to Heroku. The problem is the localhost server I open on my computer is HTTP, and my HTTPS website can't send data from HTTPS (heroku site) to HTTP (local machine: localhost). Is there any way I can share the data between them?
This is the code used to connect to localhost written on the heroku client side site:
const socket = io("https://192.168.1.15:16", { transports: ['websocket', 'polling', 'flashsocket']});
While this is what I use in my local machine:
const httpServer = require("http").createServer(app);
const io = require("socket.io")(httpsServer,{
});
as per socket.io documentation
I get this error:
Mixed Content: The page at '**The website**' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://192.168.1.35:16/socket.io/?EIO=4&transport=websocket'. This request has been blocked; this endpoint must be available over WSS.
Like #R3FL3CT says, it's most likely a CORS issue - check your console to be sure.
It seems that the initial request that it makes is the one getting blocked. For example,
const socket = io('wss://echo.websocket.org/');
socket.on("connection", (socket) => {
console.log(`Connected!`)
});
Would get blocked with the error
Access to XMLHttpRequest at 'https://echo.websocket.org/socket.io/?EIO=4&transport=polling&t=Nb17pKo' from origin 'http://127.0.0.1:5501' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Whereas just using a pure WebSocket
const websocket = new WebSocket('wss://echo.websocket.org/');
websocket.onopen = e => {
console.log(`Connected!`);
}
Connected okay.
So your solution is to either roll back to an earlier version of socket.io that doesn't force cors (before v3), or just use your own WebSocket - example: https://www.websocket.org/echo.html
Here's one way you could do something to try and communicate. If you host your own version of CORS Anywhere, you can communicate with http:// websites. I have a working link you can use, if you don't want to have to host one, but here the Github is. The way it works, is that you append the URL to the end of your URL for CORS Anywhere.
e.g https://cors.anywhere.com/google.com

Is it safe to use HTTPS provided automatically by Glitch although I've only setup an HTTP express app?

I have created a simple http express app and uploaded it on glitch.
The code is as follows:
var app = require('express')();
var express = require('express');
var http = require('http').createServer(app);
app.use(express.static('./views'));
http.listen(3000, () => {
console.log('listening on 3000');
});
When I choose view app on a new window option in glitch, the url is "**https://some-server-name.glitch.me/**"
Though I have setup only HTTP protocol, I get HTTPS in url. Does this mean it is secure to use this website ?
HTTPS is typically terminated by a reverse proxy in front of your application server. You wouldn’t want to have to care about handling HTTPS in node. If you can access the URL via HTTPS, then yes, that’s secure up to the Glitch endpoint, which is the most important part of the route.
Answered by deceze in the comments section.
Would have been better if he had answered it directly !

How to handle tcp/ip raw requests and http requests on the same server

I am working on a gps tracking system and have built a server on node js.
This is how the file looks like for reference.
const net = require('net');
const lora_packet = require('lora-packet');
const dataParser = require('./dataParser');
const clients = [];
net.createServer(function(socket) {
socket.name = socket.remoteAddress + ":" + socket.remotePort;
clients.push(socket);
socket.on('data', function(data) {
console.log("Buffer sent by terminal : ");
console.log(data);
const packet = lora_packet.fromWire(data, 'hex');
const str = packet._packet.PHYPayload.toString('hex');
dataParser.parse_data(str, socket);
});
socket.on('end', function() {
clients.splice(clients.indexOf(socket), 1);
//broadcast(socket.name + "has left the cartel.\n");
});
function broadcast(message, sender) {
clients.forEach(function(client) {
if (client === sender) client.write(message + "\nsent\n");
return;
client.write(message);
});
process.stdout.write(message);
}
}).listen(8080);
console.log("cartel is running on the port 8080\n");
This server file handles only requests from the hardware and processes raw tcp/ip requests.
I want the server to handle http requests also and want to incorporate routing feature in the server too for client side applicarions for browser.
1) Is there any way that http requests can also be handled by the same server or should I open another port and deploy an express node js app on that?
2) If I use the same 8080 port for http, how can the routing be achieved?
3) If I use different ports for http and raw tcp/ip, what would be the best way for communication between the two server. The communication between tcp/ip server and http server should happen via socket(sending data dynamically).
From http server using socket, data has to be sent dynamically to browser to update live location
So is the flow right?
Hardware (<---->)TCP/IP server(<--->)Http server(<--->)Browser
If more information is needed to solve the query, I'll provide with that!
Thank you
It's very complicated to try to speak multiple protocols on the same port. It requires some sort of scheme at the beginning of each connection to sample the incoming data and identify which protocol it is and then shunt that connection off to the right code to handle that protocol. I wouldn't suggest it.
It is way, way easier to just open a second server on a different port for an Express server to field your http requests. Very simple. You can do it right in the same app. Because both servers can be in the same app, you can just directly read from one connection and write to the other. There's no need for interprocess communication.
Is there any way that http requests can also be handled by the same server or should I open another port and deploy an express node js app on that?
Open another port. No need to write another app unless you have a specific reason to use two processes. You can put both the plain TCP server and the Express server in the same node.js app.
If I use the same 8080 port for http, how can the routing be achieved?
It's not easy. Not suggest to use the same port for multiple protocols.
If I use different ports for http and raw tcp/ip, what would be the best way for communication between the two server. The communication between tcp/ip server and http server should happen via socket(sending data dynamically).
You can put both servers in the same node.js app and then you can just read/write directly from one to the other with the same code. No need for interprocess communication.
From http server using socket, data has to be sent dynamically to browser to update live location
Sending data dynamically to a browser usually means you want the browser to hold something like a webSocket or socket.io connection to your server so you can then send data to the browser at any time over the existing connection. Otherwise, you would have to "wait" for the browser to request data and then respond with the data when it asks.

Nodejs http server cannot handle, proxy enabled request from Amazon Load balancer

I have a nodeja HTTP server which was woking good until I enabled Proxy at amazon Load balancer (which is on TCP protocol) to get client's IP.
I wonder How TCP server of nodejs works perfectly , but http server cannot
var net = require('net');
var proxy_protocol = require('node-proxy-protocol');
net.createServer(function(socket) {
proxy_protocol.parse(socket, function(error, obj) {
console.log(obj); //returns required client's info
});
});
but, why http server fails to do , if I replace "net" with "http":
This does not work
var net = require('http');
var proxy_protocol = require('node-proxy-protocol');
http.createServer(function(req,res) {
proxy_protocol.parse(req, function(error, obj) {
console.log(obj); //returns nothing
});
});
although I know that HTTP (usually) operates over TCP, so it must work for both.
basically I think, My Http Server is not able to handle TCP request from Load Balancer.
Please let me know where am I going wrong.
My nodejs HTTP server was not handling TCP from Load Balancer, so I switched Load Balancer's Protocol to HTTP.and now my HTTP server works well.

Localhost refuses connection from Javascript

I am making a single web app that takes information from MYSQL database and displays it on screen using AngularJS and NodeJS. I have set up a node.js server that gives out JSON file from a database. It works fine if I connect to it like this: 192.168.1.57:8888 which is my home server ip or remote connecting my server and using localhost:8888. Doing this downloads the JSON file on my computer.
However. If I'm using javascript to get JSON file from the server it gives me this error:
GET http://localhost:8888/ net::ERR_CONNECTION_REFUSED
I have tried connecting to the server with both AngularJS and JQuery and they both give the same error. I've also tried 127.0.0.1 and that doesn't work either. What can I do to fix it or can I do this with a better alternative way?
This is the server code in node.js
var http = require("http");
mysql = require("mysql");
var connection = mysql.createConnection({
user: "test",
password: "test",
database: "test"
});
http.createServer(function (request, response) {
request.on('end', function () {
connection.query('SELECT * FROM feedback;', function (error, rows, fields) {
response.writeHead(200, {
'Content-Type': 'x-application/json'
});
response.end(JSON.stringify(rows));
});
});
}).listen(8888);
this is the client side in angularJS:
(function(){
var app = angular.module('question', [ ]);
app.controller("ServerController", [ '$http', function($http){
$http.get("http://localhost:8888").success(function(data,status,headers,config){
console.log("success");
}).error(function(data,status,headers,config){
console.log("error");
});
} ]);
}
)();
Taking a guess at it, you're running into the Same Origin Policy, which requires that the page making the ajax request be in the same origin as the resource it's requesting (or that the server serving the resource supports CORS and allows the page's origin).
Two different ways this might be hitting you (I can't tell which, the question doesn't give enough information):
If the browser code is running in a page loaded from the file system, not via HTTP, then it's a cross-origin request because the protocols don't match (file: vs. http:).
If the page has not been loaded from localhost:8888, but instead from some other port on localhost, then the origins don't match because the port numbers are different.

Categories

Resources