# Failing to get API data from WebSocket

**URL:** <https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483>\
**Category:** General\
**Created:** [24 November 2020 19:37 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483 "2020-11-24T19:37:18Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Letis009](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@Letis009](https://discourse.nodered.org/u/Letis009)\
**Post date:** [24 November 2020 19:37 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483/1 "2020-11-24T19:37:19Z")

</div>

Hi

Which Node can send http request like packets to a ws://...../ url  
or direction to replicate html ajax into node red

I have a flow with a simple function,  
HTTP request node sends POST with JSON credentials  
msg returned has a header with \_session\_id  
use switch and function nodes to add headers for cookies and data types  
POST all this to HTTP request node ( to instruct start sending events )  
and websocket out (connecting to API server on corrrect path)  
tried GET to websocket no change

In wireshark I get protocol switch 101 if i send ws:// to http://  
but I dont see the websocket traffic at all and the socket closes immediately  
If I look closely at wireshark for attached html I see the ws://192..../wsapi GET  
but I cant replicate this in node-red as WS node traffic doesnt show in wireshark  
AT all

If I run the html scripts I am trying to replicate in browser  
everything works  
tried to use UI builder to put that HTML in but later there will be issues with cross-domain and HTTPS requirements

```auto
[{"id":"21b264d9.35577c","type":"function","z":"b88045d9.169908","name":"","func":"//var bs = flow.set('headers', msg.headers);\n//msg = \"\";\nvar ws_Key = msg.payload._Key;\nvar bs_call = flow.get('headers.bs-session-id');\nvar hd_call = flow.get('headers.Cookie');\nmsg.headers = {};\nmsg.headers['Connection'] = 'Upgrade',\nmsg.headers['Upgrade'] = 'websocket',\nmsg.headers['Sec-WebSocket-Version'] = '13',\nmsg.headers['bs-session-id'] = bs_call,\nmsg.headers['Sec-WebSocket-Key'] = ws_Key,\nmsg.headers['Sec-WebSocket-Extensions'] = 'permessage-deflate; client_max_window_bits',\nmsg.headers['Cookie'] = hd_call;\nvar j = \"GET\";\nmsg.method = j;\n//var i = '192.168.0.109/wsapi';\n//msg.url =i;\n//msg.headers[''] = '';\nmsg.payload = 'bs-session-id' + '=' + bs_call;\n//msg.statusCode = \"\";\n//node.send(msg);\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":760,"y":420,"wires":[["99045d0d.b2bfc","132534d1.93139b"]]},{"id":"76f3973d.ff3dc8","type":"change","z":"b88045d9.169908","name":"Cookie","rules":[{"t":"set","p":"headers.Cookie.WebLoginHandle","pt":"msg","to":"1599147251652","tot":"str"},{"t":"set","p":"headers.Cookie.io","pt":"msg","to":"vATAy6Qfvd-zamHCAAAB","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":340,"wires":[["c069aaea.685a98"]]},{"id":"99045d0d.b2bfc","type":"debug","z":"b88045d9.169908","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":930,"y":420,"wires":[]},{"id":"c069aaea.685a98","type":"objectid","z":"b88045d9.169908","name":"","selectedProperty":"_Key","x":750,"y":380,"wires":[["21b264d9.35577c"]]},{"id":"d880e506.743918","type":"inject","z":"b88045d9.169908","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":440,"y":300,"wires":[["5e2b4adc.c8c1c4"]]},{"id":"e8b8c177.73141","type":"http request","z":"b88045d9.169908","name":"","method":"POST","ret":"obj","paytoqs":"query","url":"http://192.168.0.109/api/login","tls":"","persist":true,"proxy":"","authType":"","x":730,"y":300,"wires":[["76f3973d.ff3dc8","49f12eda.0e198"]]},{"id":"5e2b4adc.c8c1c4","type":"change","z":"b88045d9.169908","name":"Sign In","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t \"User\": {\t \"login_id\": \"admin\",\t \"password\": \"Admin123\"\t }\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":590,"y":300,"wires":[["e8b8c177.73141"]]},{"id":"132534d1.93139b","type":"websocket out","z":"b88045d9.169908","name":"","server":"","client":"a7dfc535.c07308","x":830,"y":460,"wires":[]},{"id":"fdce8ffb.71638","type":"debug","z":"b88045d9.169908","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":380,"wires":[]},{"id":"57fd0f16.5c0bc","type":"function","z":"b88045d9.169908","name":"","func":"var bs = flow.set('headers', msg.headers);\nvar bs_call = flow.get('headers.bs-session-id');\nvar hd_call = flow.get('headers.Cookie');\nmsg.headers = {};\nmsg.headers['bs-session-id'] = bs_call,\nmsg.headers['Content-Type'] = 'application/json',\nmsg.headers['Cookie'] = hd_call,\nmsg.headers['X-Requested-With'] = 'XMLHttpRequest';\n//msg.headers[''] = '';\nmsg.payload = 'bs-session-id='+bs_call;\nvar j = \"POST\";\nmsg.method = j;\nvar i = 'http://192.168.0.109/api/events/start';\nmsg.url =i;\nnode.send(msg);\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":940,"y":340,"wires":[["4063d1d5.5fa49","98033d4b.ac8c6"]]},{"id":"4063d1d5.5fa49","type":"http request","z":"b88045d9.169908","name":"","method":"use","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":true,"proxy":"","authType":"","x":950,"y":380,"wires":[["fdce8ffb.71638"]]},{"id":"49f12eda.0e198","type":"change","z":"b88045d9.169908","name":"Cookie","rules":[{"t":"set","p":"headers.Cookie.WebLoginHandle","pt":"msg","to":"1599147251652","tot":"str"},{"t":"set","p":"headers.Cookie.io","pt":"msg","to":"vATAy6Qfvd-zamHCAAAB","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":940,"y":300,"wires":[["57fd0f16.5c0bc"]]},{"id":"98033d4b.ac8c6","type":"debug","z":"b88045d9.169908","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1090,"y":340,"wires":[]},{"id":"a7dfc535.c07308","type":"websocket-client","z":"","path":"ws://192.168.0.109:/wsapi","tls":"","wholemsg":"true"}]

```

```auto
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=windows-1252">
    <title>API 2</title>
  </head>
  <body>
    <div>
      <button id="loginBtn">Login</button> </div>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="crossorigin="anonymous"></script>
    <script>
		$(document).ready(function(){
			var API_HOST = 'https://192.168.0.104:443',
				WS_HOST = 'wss://192.168.0.104:443',
				LOGIN_API_URI = API_HOST + '/api/login',
				WS_URI = WS_HOST + '/wsapi',
				WS_EVENT_START_URI = API_HOST + '/api/events/start';
			
			$('#loginBtn').load(function(){
				var loginData = {
					'User':{
						'login_id': "admin",
						'password': "Admin123"
					}				
				};				
						
			$.ajax({
					url: LOGIN_API_URI,
					type: 'POST',
					dataType: 'json',
					data: JSON.stringify(loginData),
					contentType: 'application/json',
					success: function(data, textStatus, request){						
						var bsSessionId = request.getResponseHeader('bs-session-id'),							
							ws = new WebSocket(WS_URI);
							
						ws.onopen = function(){  
							ws.send('bs-session-id' + "=" + request.getResponseHeader('bs-session-id'));
							setTimeout(function(){postAPI2()}, 1000)
	
							function postAPI2(){$.ajax({
								url: WS_EVENT_START_URI,
								type: 'POST',
								dataType: 'json',								
								contentType: 'application/json',
								beforeSend: function(request) {
									request.setRequestHeader("bs-session-id", bsSessionId);
								},
								success: function(data, textStatus, request){						
									console.log(data, textStatus, request);
								},
								error: function(err){
									console.log(err);
								},
							});     
						     }  
						};  
						
						ws.onmessage = function (event) {
							console.error(event);
						};
					},
					error: function(err){
						console.log(err);
					},
				});       
			});
		});
	</script>
  </body>
</html>

```

```auto
GET /wsapi HTTP/1.1
Host: 192.168.0.109
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36 Edg/87.0.664.41
Upgrade: websocket
Origin: http://192.168.0.109
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8

Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

HTTP/1.1 101 
Upgrade: websocket
Connection: upgrade

X-Content-Type-Options: nosniff
X-XSS-Protection: 1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: SAMEORIGIN
Date: Tue, 24 Nov 2020 19:09:56 GMT

.....$..T	....YtQ..
.i..7l....%......h.......n.......$.%..R..........T%+.j..X49?.$.d..........%..*...e&...L..5511.0.42T.AH..$.........Hw..K.....

```

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [24 November 2020 23:41 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483/2 "2020-11-24T23:41:47Z")

</div>

Sorry, maybe I'm tired but I can't understand what you are trying to do.

> [@Letis009](#):
>
> Which Node can send http request like packets to a ws://...../ url  
> or direction to replicate html ajax into node red

That doesn't seem to make sense. When you start a websockets connection, it starts automatically as an http(s) connection and then upgrades to a ws(s) if it can. Websockets can be blocked by proxies and content aware firewalls in some cases so an upgrade is not always possible.

So you can send custom headers to the initial handshake in a websocket connection. However, once the upgrade happens, no further custom headers are allowed. It is for this reason that you cannot do proper session handling over websockets, if you need to keep checking the session validity, you need to use the websocket data rather than headers.

---

<div class="post-metadata">

**Author:** ![Letis009](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@Letis009](https://discourse.nodered.org/u/Letis009)\
**Post date:** [25 November 2020 05:37 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483/3 "2020-11-25T05:37:41Z")

</div>

The connections are all resident on the same server so the address can be localhost as an example or the same address

Lets say i have 5 browsers connected to my nginx site if they all initiate an upgrade to websocket all traffic is not broadcast to all 5 but along to the individual hosts

I need to start a http handshake then once authenticated upgrade to ws .  
If I try using the core ws node then i get all the up to the upgrade but the nginx server sends 1 websocket packet and the node red ws node dont open port and accept traffic

How does ws identify which browser to send traffic to

---

<div class="post-metadata">

**Author:** ![Letis009](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@Letis009](https://discourse.nodered.org/u/Letis009)\
**Post date:** [25 November 2020 05:43 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483/4 "2020-11-25T05:43:23Z")

</div>

Or i am looking for advise on which other route to replicate the ajax in the working html page which is using ws nodejs module

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [25 November 2020 22:09 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483/5 "2020-11-25T22:09:41Z")

</div>

I think this might be on the backlog for Node-RED? [https://trello.com/c/nx4islGu/80-ws-customise-options-on-outbound-ws-connections](https://trello.com/c/nx4islGu/80-ws-customise-options-on-outbound-ws-connections)

If you use uibuilder, it supports the insertion of a [Socket.IO](http://Socket.IO) middleware function that will allow you to do authentication at the point of the initial http connection.

---

<div class="post-metadata">

**Author:** ![Letis009](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@Letis009](https://discourse.nodered.org/u/Letis009)\
**Post date:** [25 November 2020 23:16 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483/6 "2020-11-25T23:16:11Z")

</div>

It seems exactly like that request . I couldnt see if anything came of the initial thread

Do you somewhere to find info on the [socket.io](http://socket.io) and ui builder option

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [26 November 2020 02:04 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483/7 "2020-11-26T02:04:12Z")

</div>

> [@Letis009](#):
>
> It seems exactly like that request . I couldnt see if anything came of the initial thread

It is still on the backlog. There is the setting for incoming requests of course but not outgoing.

> [@Letis009](#):
>
> Do you somewhere to find info on the [socket.io](http://socket.io) and ui builder option

uibuilder doesn't do outgoing requests either. Check the `security` branch on GitHub which has more documentation on websocket security for how it works.

---

<div class="post-metadata">

**Author:** ![Letis009](https://avatars.discourse-cdn.com/v4/letter/l/b3f665/32.png) [@Letis009](https://discourse.nodered.org/u/Letis009)\
**Post date:** [26 November 2020 06:00 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483/8 "2020-11-26T06:00:21Z")

</div>

Thank you Julian

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [25 January 2021 06:00 UTC](https://discourse.nodered.org/t/failing-to-get-api-data-from-websocket/36483/9 "2021-01-25T06:00:26Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
