How can i connect a Javascript client to a Python-SocketIO server? - javascript

I'm just getting started to Python-SocketIO, i created an example server, it looks like this:
import eventlet
import socketio
sio = socketio.Server()
app = socketio.WSGIApp(sio, static_files={
'/': {'content_type': 'text/html', 'filename': 'index.html'}
})
#sio.on('connect')
def connect(sid, environ):
print('connect ', sid)
#sio.on('msg')
def message(sid, data):
print('message ', data)
#sio.on('disconnect')
def disconnect(sid):
print('disconnect ', sid)
if __name__ == '__main__':
eventlet.wsgi.server(eventlet.listen(('', 5000)), app)
Then, i have an HTML file which is running on a Django application, i would like to connect that client to my Python-SocketIO server:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script>
socket = io.connect('');
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
socket.on('msg',function(data) {
console.log('Received a message from the server!',data);
});
socket.on('disconnect',function() {
console.log('The client has disconnected!');
});
// Sends a message to the server via sockets
function send(message) {
socket.send('msg',message);
};
</script>
The problem is that, on my client side, i keep getting the following errors:
Access to XMLHttpRequest at 'http://localhost:5000/socket.io/?EIO=3&transport=polling&t=N5eSEa2' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
localhost:5000/socket.io/?EIO=3&transport=polling&t=N5eSEa2:1 Failed to load resource: net::ERR_FAILED
My Django server is running on http://127.0.0.1:8000/. Can anyone help me find what i'm doing wrong?

Set the CORS header on your server:
sio = socketio.Server(cors_allowed_origins='*')
(Source)

Related

Cors is not working for two different origins

I have two servers, frontend (Next.js) and backend (express.js api server).
Frontend server is running without any additions. But I have an nginx proxy for backend.
So far everything is good because they are not connected yet.
Frontend: is working as it should be.
Backend: I can make calls directly from the backend itself (by self origin).
When I make a fetch get call from my frontend server to the backend server, it normally gives a cors error because the origins are different.
For this, I set the backend server with cors:
// /src/middlewares/cors.ts
import cors from 'cors';
const whitelist = new Set(['http://192.168.1.106:3000', 'https://192.168.148.132']);
// frontend: http://192.168.1.106:3000
// backend: https://192.168.148.132
const corsOptions = {
optionsSuccessStatus: 200,
origin: (origin: any, callback: any) => {
console.log('origin: ' + origin);
if (whitelist.has(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
// credentials: true,
};
export default cors(corsOptions);
and
// /app.ts
import cors from './middlewares/system/cors.js';
.
.
// setup cors
app.options('*', cors);
app.use(cors);
.
.
After doing this, I reach my main goal. The frontend server can make call to the backend server.
output:
But this time I notice a problem. I can't send self request to backend anymore (by self origin).
When dealing with this I looked at the origins that came to the /src/middlewares/cors.ts file that I showed above.
for frontend:
for backend:
I am using self signed ssl in nginx for back server.
And there is not any cors relevant headers in conf.
How can i solve this situation?
(If I'm missing something, you can point it out in the comments.)
The Origin header is only set in cross-origin requests. If you call your backend directly, the Javascript value is undefined, and in this case you must not restrict anything. You could, for example, write
if (!origin || whitelist.has(origin)) {
callback(null, true);
}

How can i pass extra header Info in Angular and socket.io?

Based on what i read and tested on basic javascript clients i can pass extra headers in my Angular Client which will then be avail on my NodeJs server in the
socket.handshake . But i am not sure what i am missing or what i am doing wrong since below code does not create
async socketInit() {
this.client = io(`${environment.socketUrl}`, {
transportOptions: {
polling: {
extraHeaders: {
Authorization: "Bearer authorization_token_here"
}
}
}
});
await new Promise((res) => {
this.client.on('connect', () => {
this.isConnected = true;
this.socketId = this.client.id;
this.client.on('disconnect', () => this.isConnected = false);
res();
});
})
.catch((e) => console.log(`Socket.io error: ${e.message}`));
}
for some reason this causes the connect to fail as i can see in my debug console of the angular that socket.io has a TransportError
In my case, I was trying to connect to a web-socket server on port 5001, while my angular app was opened on port 4200. When I added extraHeaders to the client options, the browser started to throw the CORS error like this:
origin has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
The ports are not the same, and that's the cause of the cross-origin problem.
I've fixed it by setting my web-socket server port, the same as the web server, and opening the webpage on that port.

Client side unable to hit its own server endpoint

I've a AngularFullStack project in which I'm trying to hit my project's server endpoint using the following code, however the problem is the call isn't going through from angular client side to the nodejs server. Since it's my first project, I've little to no idea what might be going wrong that might be causing this weird conflict.
ClientSide:
$http({
method: 'POST',
url: '/api/soapAPIs/soapAPI',
data: request,
headers: {
'Content-Type': 'application/json'
}
})
.then(function(response) {
console.log("response from server is: ", response);
})
.catch(function(error) {
console.log("error in calling server is: ", error);
});
I have installed CORS on server side and wrote the following code in app.js but still it doesn't work.
Server App.js
// Setup server
var app = express();
var cors = require('cors');
//add cors to do the cross site requests
app.use(cors());
Server Endpoint Code:
export function soapAPI(req, res) {
console.log("SERVER SIDE ", req.body);
res.status(statusCode).json({"status":"success"});
res.send();
}
Following are the problems:
If I try to hit nodejs endpoint like this /api/soapAPIs/soapAPI, the browser shows pending request and it never goes to the server.
When I add the full classified url for the endpoint like this http:localhost:9000/api/soapAPIs/soapAPI, it hits the endpoint but then the client never receives response from the server. I don't want to provide the full classified URL on the client side for obvious reasons.
How can I resolve this issue? Please let me know if you need any other code/information.
EDIT:
By using full classified path, the server endpoint gets hit but its response is never received by the client side. I get this error in browser:
Possibly unhandled rejection: {"data":null,"status":-1,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"/api/things","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":""}
Uncomment the following line:
/*mongoose.connect(config.mongo.uri, config.mongo.options);
mongoose.connection.on('error', function(err) {
console.error(`MongoDB connection error: ${err}`);
process.exit(-1); // eslint-disable-line no-process-exit
});
*/
Basically this is causing your controller to not return any response because your mongoose models are being referenced but the connection to mongo fails.

Cant connect to a external server (api) in socket io

Im trying to connect to a only api but is not working, is giving me a error of:
XMLHttpRequest cannot load https://api.sports/socket.io/?api_key=aredasdasdadds&EIO=3&transport=polling&t=LsYSPsv. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 596.
The strange thing is in the error showing a different api url.
My code is:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h1>Web socket</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script type="text/javascript">
// Create SocketIO instance, connect
var socket = new io('https://api.sports.com/soccer-/eu/en/matches/summary.json?api_key=aredasdasdadds');
socket.connect();
// Add a connect listener
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
// Add a connect listener
socket.on('message',function(data) {
console.log('Received a message from the server!',data);
});
// Sends a message to the server via sockets
function sendMessageToServer(message) {
socket.send(message);
}
</script>
</body>
</html>
What is your server?
First, ou have to check that the version of socket.io is the same on the client and on the server (I see that on client is 2.0.3).
Secondly, you only need use the domain of your web like this:
var socket = io.connect('ws://https://api.sports.com:8443/', {transports: ['websocket']});
And set the port to listen, usually is 8443 for https.
Regards!

Can't figure out "No 'Access-Control-Allow-Origin' header" in Node Express with CORS and Mandrill

I've been reading up enough to know I'm lost on this one. The solutions on other threads don't seem to help.
I have a page at pages.samedomain.com calling the mandrill api in my Node site at apps.samedomain.com. Using ORM, I am able to write through the tables route just fine. After the table is written and the page receives confirmation, it's supposed to fire to the email route. When run locally, both work fine. When deployed, I get...
XMLHttpRequest cannot load http://apps.samedomain.com/.../.../mail/4847775376401843. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://pages.samedomain.com' is therefore not allowed access. The response had HTTP status code 502.
In my app.js I have...
var cors = require('cors');
app.use(cors());
In my routes file I have...
module.exports = function(appRouter) {
var mandrill = require('mandrill-api/mandrill');
var mandrill_client = new mandrill.Mandrill(process.env.MANDRILL_API_KEY);
appRouter.route('/.../mail/:first_list_id').post(function(req,res){
req.models.know_me_2016
.find({list_id:req.params.first_list_id})
.run(function(err, results){
if (err) {
res.send(err);
} else {
var template_content = [{
"recipient": <stuff> ,
"content": <stuff>
}];
var message = {
<mandrill message object stuff>
};
}
mandrill_client.messages.sendTemplate({
"template_name": <template-name>,
"template_content": template_content,
"message": message}, function(result) {
console.log(result);
//I tried adding header stuff but it didn't help, maybe in wrong place? I thought CORS library was going to take care of this part?
res.header("Access-Control-Allow-Origin", "http://interactives.dallasnews.com");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
//It sends successfully when run local
res.send("Email sent successfully");
}, function(e) {
// Mandrill returns the error as an object with name and message keys
console.log('A mandrill error occurred: ' + e.name + ' - ' + e.message);
// A mandrill error occurred: Unknown_Subaccount - No subaccount exists with the id 'customer-123'
});
});
});
}
My Mandrill key is set to accept all IPs.
Any insight would be appreciated.
You need to add allowed origins to the white list when initializing cors:
var whitelist = [
'http://samedomain.com',
'http://apps.samedomain.com',
'http://pages.samedomain.com'
// list whatever possible domains you have
]
var globalCorsOptions = {
origin: function(origin, callback) {
callback(null, whitelist.indexOf(origin) !== -1);
}
};
var cors = require('cors');
app.use(cors(globalCorsOptions));
In this particular case, it turns out the problem was with the lack of an updated .env file. Our private git ignores .env files so the credentials weren't being posted. Mandrill was unable to connect. Once the Mandrill credentials were inserted and the .env remote updated, it started working as expected.

Categories

Resources