CORS with socket.io - javascript

I'm having trouble with CORS on a node.js app using express.io. I'm hosting the socket.io client js remotely since this needs to works as a remote app.
<script src="resources/js/socket.io.min.js"></script>
It's hosted on OpenShift
server.js:
var ipaddr = process.env.OPENSHIFT_NODEJS_IP || "localhost";
var port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
var express = require('express.io');
// magical express.io
var app = express();
// Enables CORS
var enableCORS = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With, *');
// intercept OPTIONS method
if ('OPTIONS' == req.method) {
res.send(200);
} else {
next();
};
};
app.configure(function() {
// enable CORS!
app.use(enableCORS);
});
app.http().io();
app.io.set('origins', '*:*');
//.... other stuff
app.listen(port, ipaddr);
Then on the client:
var socket = io.connect(window.chat_url);
When I run the client from localhost:8888 with the server localhost:8080 socket.io works fine.
When I run the client from localhost:8888 and the server on odechat-latestsightings.rhcloud.com then socket.io times out:
Firebug:
GET http://nodechat-latestsightings.rhcloud.com:8888/socket.io/1/?t=1391542144169 1m 16s
The other routes work fine:
GET http://nodechat-latestsightings.rhcloud.com/rooms 200 OK 664ms
I just can't figure this out

Also, if your server is on openshift then you should bind to port: 8000 to use websockets since that is the port openshift's nginx reverse proxy has public access.
You can read more from here: https://developers.openshift.com/en/managing-port-binding-routing.html

Related

Can't connect socket.io node server to react frontend. "POST http://localhost:3000/socket.io/?EIO=3&transport=polling&t=MoHNIJT 404 (Not Found)"

I have created a frontend in react and a backend in express nodejs, and I am using socket.io for the client and server to communicate.
When I load the react page I get the following error every second:
Failed to load resource: the server responded with a status of 404 (Not Found)
I have set the frontend to run on port 3000 and the server to run on port 3500. The failed connect requests are being sent to the address:
http://localhost:3000/socket.io/?EIO=3&transport=polling&t=MoHUt8D
Below is the setup for the node backend:
const bodyParser = require('body-parser');
const https = require('https');
const fs = require('fs');
const express = require('express');
const app = express();
app.use(bodyParser.json());
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin',
'https://www.localhost:3000');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, PATCH, PUT');
res.header('Access-Control-Allow-Credentials', 'true');
next();
});
const server = https.createServer(app);
var io = require('socket.io')(server);
console.log('Server listening on port 3500.');
server.listen(3500);
And the client side connects as follows:
import openSocket from "socket.io-client";
const hostURL = "http://localhost:3500";
const socket = openSocket()
Any advice on how to stop the error and have the front and backend working with socket.io
You need to use the http library instead of the https one.
server.listen(3500) does not support https. If for some reason you do need to use it, you can reference this answer.
Also, on your client you need to tell the socket library the URL of the host, otherwise it will default to window.location as mentioned here in the docs which seems to be your case as you mentioned the requests are directed towards localhost:3000 and your server is on localhost:3500 so change this
import openSocket from "socket.io-client";
const hostURL = "http://localhost:3500";
const socket = openSocket()
to this
import openSocket from "socket.io-client";
const hostURL = "http://localhost:3500";
const socket = openSocket(hostURL)

How do you find the url for a node.js express site on a VPS?

I recently purchased a VPS from OVH for the hosting of my discord bot. It has a stats.json page that I need to have another site GET to, but I can't seem to find my VPS's express site.
I'm trying to access it from my vpsXXXXXX.vps.ovh.ca, but I get the error: This site can’t be reached. I have the following on my main code:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.get("/", (request, response) => {
response.sendStatus(200);
});
app.get('/stats', function(request, response) {
response.sendFile(__dirname + "/stats.json");
});
And even with this code, I get no response from the VPS's URL.
I'd want to have my glitch.me site to be able to GET the data from the stats.json, but I can't seem to find or figure out a way to get a URL for my VPS.
Does anyone know how to connect a URL or use the VPS URL?
Thank You!
Codingpro
You forgot to listen. Set the environment port instead
var port = process.env.PORT || 3000
app.listen(port, () => console.log(`Online on port ${port}!`))
I figured out my issue:
I had forgotten to add the app.listen() to the code. Here is what I added to fix it:
var port = 3000
/*
* Set your server's port. This made mine vpsXXXXXX.vps.ovh.ca:3000.
* HTTP standard port: 80
* HTTPS standard port: 443
*/
app.listen(port, () => console.log(`Online on port ${port}!`))

Nodejs local API does not work

I'm doing an university project with NodeJs but I have some trouble in testing it in local.
This is the problem:
I have a GET API "/api/services/names" and the NodeJS server is running on port 8080.
If I test the API with Postmanor by putting the URL in the Chrome bar ("http://localhost:8080/api/services/names") it works fine and I can get my response.
The problem is that if I test it in my local website using fetch() inside this function:
function fetchServicesNames(){
fetch('/api/services/names')
.then(function(response){
return response.json();
})
.then(function(data){
data.map(addServiceLink);
});
}
The Javascript console gives me this error:
Failed to load resource: the server responded with a status of 404 (Not Found)
I noticed that when I hover the console error, it shows the request string "http://localhost/api/services/names" without the port. But I don't think this is the problem because when I deploy the application on the Heroku platform it works fine... the problem is just in localhost (I'm working with a mid 2010 macbook pro with Mac OSX 10.10.2).
Any help is appreciated, thank you in advance.
Edit:
as requested I'm adding here the server code
// server.js for Hypermedia Application project.
// BASE SETUP
//============================================================
// call packages
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(express.static(__dirname + "/public"));
// we use body-parser, so we need to be able to read data either from
// GET and POST:
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// setting the application port to listen
var serverPort = process.env.PORT || 5000;
// --- database connection omitted ---
// API ROUTES
// ================================================================
// first of all: get the Router
var router = express.Router();
/**
* Services names
* /api/services/names - get - get all services ids and names
*/
router.route('/services/names')
.get(function (req, res) {
Service.find({}, 'id name', function (err, services) {
if (err)
res.send(err);
res.json(services);
});
});
// --- Other APIs omitted ---
// REGISTER ROUTES:
// all of our routes will be prefixed with /api
app.use('/api', router);
// START THE SERVER
//===================================================================
app.set("port", serverPort);
app.listen(serverPort, function() {
console.log(`Your app is ready at port ${serverPort}`);
});
at your server page you add
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
before your API's
it might help you for CORS
Dear i suggest you to write total Path like
http://localhost:<your port number>/api/services/names
inside fetch()and u check once
I too tried and i got Success
Hi try modifying the line like fetch('http://'+window.location.host+':8080/api/services/...)

Express session is undefined when accessing external website

I'm trying to use express sessions to store user credential information for my website. Unfortunately, while I managed to get the website to work from my local machine, express session is empty during every request from the hosted website.
To make this easier to understand:
server:
Node.JS app
hosted website (plain HTML, javascript)
req.session always empty
local:
local server accessible by localhost.com (hosts was edited to redirect localhost.com to 127.0.0.1)
req.session has the things I set in it
The website files are identical/synced & both connect to the same server.
requests from the website are ajax with default:
$.ajaxSetup({
xhrFields: {
withCredentials: true //for server-side sessions
}
});
server app.js setup:
var express = require('express');
var expsession = require('express-session');
var config = require('./config');
var app = express();
app.set('port', process.env.PORT || 3333);
app.use(require('method-override')());
app.use(require('morgan')('dev'));
app.use(require('body-parser')({ keepExtensions: true}));
app.use(require('cookie-parser')());
app.use(expsession({
secret: 'stufffandthings',
store: new expsession.MemoryStore({reapInterval: 600000})
}));
app.use(function(req, res, next) {
console.log('From: ' + req.get('origin'));
if(config.origins.indexOf(req.get('origin')) > -1){ //if in list of allowed origins
res.header("Access-Control-Allow-Origin", req.get('origin')); //allow them in
console.log('Set access control to allow origin');
}
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Authorization, Content-Length');
res.header('Access-Control-Allow-Credentials', true);
res.header("Cache-Control", "no-cache");
next();
});
config.origins contains my http://localhost.com:3700 & http://hostedwebsite.com:8080. Both the localhost and local website are allowed origins.
Edit:
On the hosted website, if you don't leave the page and keep doing ajax requests the session object remembers you. Huh?
app.use(express.static(path.join(__dirname, '/public')));
Had to be above the express-session middleware declaration. It's a bug with express-session module.

express.js app throws no response

Here is a express server code:
var express = require('express');
var mysql = require('mysql');
var app = express();
app.use(express.bodyParser());
app.use(express.static('public'));
var connection = mysql.createConnection({
host : 'localhost',
user : 'someuser',
password : 'somepassword',
database: 'some_database'
});
connection.connect();
app.get('/users/authenticate', function(req, res){
res.setHeader('Content-Type', 'application/json');
res.send({test:"test"});
res.end();
});
app.listen(3000);
console.log('Listening on port 3000');
Now when i issue a get request to this API, i get nothing in response tab of network console though response code is 200 ok. Please shed some light. I expect JSON data here.
Here is what i get in my console:
Try using:
app.get('/users/authenticate', function(req, res){
res.json({foo:'bar'});
});
Also, if you are doing this across different domains, you will need to setup CORS.
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
app.configure(function() {
app.use(allowCrossDomain);
}
...and if you are attempting to test CORS from a localhost, you will need to open Chrome with some security disabled. If you are on a Mac, it is done with the following command. Just make sure Chrome is closed before you run it.
`open -a Google\ Chrome --args --disable-web-security`
The code is ok. I am getting {test:"test"} both from browser and also using
curl http://localhost:3000/users/authenticate

Categories