0

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.
neryushi
  • 128
  • 1
  • 12
  • How exactly does one “send to” the other in the first place? – deceze Apr 26 '21 at 17:55
  • @deceze when I set up socket.io, i use: new socket.io()(domain) and instead of the domain i put my local IP address and port – neryushi Apr 27 '21 at 04:39
  • Why don't you have your localhost server call the heroku server instead? Bypasses any router / firewall issues and websockets are bidirectional, so once the connection is up it doesn't matter which side initiated it. – Meirion Hughes Apr 30 '21 at 07:09
  • @MeirionHughes because I need to send data from the client side of heroku... – neryushi Apr 30 '21 at 09:43
  • Maybe I'm missing something - but websockets are _bidirectional_: either side can send data. I'll wager its typical for IOT devices to "call-home" to establish connections. – Meirion Hughes Apr 30 '21 at 09:50
  • Sockets are bidirectional, and are used for communication from client, to server, I want my computer to act as the server while the heroku client side to act as a client and communicate directly with my computer – neryushi Apr 30 '21 at 09:51
  • Could you add some code to your question where you run into `http://localhost` and `https` conflicts? `http://localhost` is often treated as `https` by browsers, for development purposes. See also https://web.dev/how-to-use-local-https/, which may work instead – Steve May 01 '21 at 05:44
  • @Steve I added some code snippets – neryushi May 01 '21 at 16:13
  • so you have a https website on Heroku and a server on your local machine and you want to send clients data to your local server? – Milad Raeisi May 01 '21 at 20:05
  • @MiladRaeisi yes, it's the phone sensor data, and I'll send it to the clients local server which will be started by an Electron app – neryushi May 02 '21 at 15:04
  • And why you are not running an instance of server code on a cloud? – Milad Raeisi May 02 '21 at 19:42
  • Couldn't you just use a proxy like CORS Anywhere to communicate with `http://` websites? – R3FL3CT May 04 '21 at 15:08
  • @MiladRaeisi What do you mean? I want to comunicate from clientside heroku to serverside - client PC – neryushi May 05 '21 at 12:09
  • @R3FL3CT how can I do it? – neryushi May 05 '21 at 12:09
  • I mean you need a server to get data from it, phones must send data to server and then your electron clients get data from that server – Milad Raeisi May 05 '21 at 17:37

2 Answers2

1

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

divillysausages
  • 7,883
  • 3
  • 25
  • 39
  • This isn't the problem... The error is: Mixed Content: The page at 'https://virtualyoke.herokuapp.com/' 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. – neryushi May 06 '21 at 14:43
  • 2
    ah, there's no much you can do in that case. Sometimes I'm able to click the padlock in the browser URL bar to allow it, but it's not on all browsers, and is in no way future proof. If you want it to work (and it's a bit weird that a public website is connecting to a local endpoint), then you need to make your socket WSS. Something like this should work: https://stackoverflow.com/a/38525463/639441 - you can generate your keys using OpenSSL – divillysausages May 07 '21 at 12:05
  • 2
    it worked!!!!! I can't thank you enough! I've been stuck on this bug for more than a week – neryushi May 11 '21 at 06:07
0

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

R3FL3CT
  • 551
  • 3
  • 14