I'm trying to use sockets to connect to a Node server I'm running localy
but I keep on getting 'info - unhandled socket.io url' on the server side
+
"XMLHttpRequest cannot load http://localhost:8080/socket.io/?EIO=3&transport=polling&t=1424356590540-0. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access." on chrome (using address localhost:8000/index.html)
// top six lines of code to see setup
var express = require('express'),
app = express(),
http = require('http'),
server = http.createServer(app),
io = require('socket.io').listen(server);
server.listen(8080);
also I'm using python SimpleHTTPServer on port 8000
client code is:
var socket = io.connect('http://localhost:8080');
socket.on('connection', function(){
console.log("connected")
});
using https://cdn.socket.io/socket.io-1.3.4.js" version of sockets.io
I'm assuming the html is irrelevant since I don't have any javascript code in it (except references to angular and jquery)
That's a problem with CORS.
Since your web page is on localhost:8000 and the Socket.io server is on localhost:8080 (two different ports, so two different servers), to allow async requests between the two of them you need to enable CORS. Browsers require that for security reasons.
Your server seems to be using Express. Enabling CORS in Express is quite easy, thanks to NPM packages like cors. Alternatively, look at some questions on SO, like: How to allow CORS?
Related
This question already has an answer here:
Getting a CORS error when trying to establish socket.io connection between back-end on localhost:3000 and front-end on localhost:8080
(1 answer)
Closed 2 years ago.
I'm trying to figure out how to create a real time chat application that uses Vue.js for the front-end, Node.js for the back-end and socket.io.
I've generated my back-end Node.js project with express-generator and the project is accessible at http://localhost:3000. In this project I have an app.js file that contains this:
var express = require('express');
var http = require('http').createServer(express);
var io = require('socket.io')(http);
io.on('connection', (socket) => {
console.log('a user connected');
});
My front-end is a Vue.js project accessible from http://localhost:8080 and the component that is meant to connect to my back-end contains this:
<template>
<div class="home">
</div>
</template>
<script>
import socket from 'socket.io-client'
export default {
mounted(){
socket.connect('http://localhost:3000')
}
}
</script>
Sadly the socket connection doesn't seem to go through. On the front-end console I get these errors -
localhost/:1 Access to XMLHttpRequest at 'http://localhost:3000/socket.io/?EIO=3&transport=polling&t=N6Kc6yn' from origin 'http://localhost:8080' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
And on the back-end console I get this error - GET /socket.io/?EIO=3&transport=polling&t=N6KcMan 404 3.089 ms - 975
I tried installing cors through npm install cors and added the required code but nothing really happened. It looks like this:
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
var http = require('http').createServer(express);
var io = require('socket.io')(http);
io.on('connection', (socket) => {
console.log('A user has connected!');
});
I can't figure out why is this happening.
Try removing this -> app.use(cors()); if the problem persist you could have a bad path.
I'm doing a little exercise to familiarise myself with AngularJS and I have my app running on http://127.0.0.1:9000/ after I execute the necessary grunt task. Now I wish to write/teach myself how to allow a Authorization/Authentication request (basically a login form). I have a seperate project that has a REST API, this is running on http://127.0.0.1:3000/ - notice the difference in port numbers. The exercise is hosted on my local machine so I wish to use CORS for my requests as browser restrictions aren't an issue and the app is for my own amusement. In my angularJS app I have included the following code in my config to allow CORS requests:
// set up CORS...
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
In my Rest API / Node Project I include the CORS middleware available from https://www.npmjs.org/package/cors and I have enabled CORS for all requests, I have included the library like so:
cors = require('cors')
and then...
app.use(cors()); // this is in my app.configure
When I test the API using the Websore REST tool the data I desire is retured however when trying to access this is my AngularJS app the Chrome JavaScript console gives me the following error:
No 'Access-Control-Allow-Origin' header is present on the requested resource
Is there anything I have missed with setting up CORS for AngularJS? Thanks in advance.
Phew, I seem to have fixed in... In my app I needed to put the requirements in the following order:
app.use(cors());
app.use(app.router);
The app.use(cors()); must come before the app.use(app.router);
If I hit my domain on any other port other than 443 I get the error below. How is it possible then to use nodejs https on different port?
Secure Connection Failed
An error occurred during a connection to mysite:8080. SSL received a record that exceeded the maximum permissible length. (Error code: ssl_error_rx_record_too_long)
For example, in the example given in the documentation they use port 8000.
// curl -k https://localhost:8000/
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
Using CentOS 6.
record_too_long often/usually means you sent non-SSL-data to a client expecting SSL.
Try to visit your site and port via HTTP (not HTTPS). If it works, you have accidentally bound an HTTP server to it, not an HTTPS server.
At this very moment I have a Node.js server running on port 3000 using HTTPS.
SSL_ERROR_RX_RECORD_TOO_LONG seems to indicate that there's a problem with the hostname (Source)
The error you've included mentions mysite:8080 which tells me that you're trying to connect to mysite:8080 and that that address doesn't exist.
To debug this, try accessing the URL through a browser or by setting up a regular HTTP and see whether it's accessible.
I'm following a simple tutorial from here:
http://addyosmani.github.io/backbone-fundamentals/
I have a node.js server running on a localhost port 4711
I have tomcat running on port 8082 and a backbone.js app as client started as index.html on that server.
But I get :
XMLHttpRequest cannot load ... api/books. Origin localhost:8082 is not
allowed by Access-Control-Allow-Origin.
1) Why? This is not file based access - indeed a plain web browser will see
htttp://localhost:4711/ and interact just fine.
2) What's the fix? (Given that part of this stack is a node.js server)
You're initiating a CORS request since the two servers are listening on different ports( index.html on localhost:8082 and your node server on localhost:4711)
In your node's http server, try setting the Access-Control-Allow-Origin header to * or to the Origin header.
http.createServer(function(req, res) {
res.header('Access-Control-Allow-Origin', req.headers['origin']);
//handle
});
I'd like to have a client application implemented in Cappuccino that uses Node.js as the server.
I have currently got Node running with Express:
var express = require( 'express' );
var app = express();
app.get( '/an_endpoint', function(req, res){
res.send('Hello From Node Express!\n');
});
app.listen(1337);
Which is verifiable with:
$ node hello_echo.js
$ curl http://127.0.0.1:1337/an_endpoint
> Hello From Node Express!
As far as the client code, it's a simple little app, with a button that does this when clicked:
// in did finish launching
[button setTitle:"Ping Node"];
[button setTarget:self];
[button setAction:#selector(doPing:)];
- (void)doPing:(id)sender
{
var connection = [CPURLConnection connectionWithRequest:[CPURLRequest requestWithURL:'http://127.0.0.1:1337/an_endpoint/'] delegate:self];
}
- (void)connection:(CPURLConnection) connection didReceiveData:(CPString)data
{
alert('Node Says: ' + data);
}
- (void)connection:(CPURLConnection)connection didFailWithError:(CPString)error
{
alert('Error: ' + error);
}
When I load the app ( from http://127.0.0.1:8080/NewApplication/index.html ) and click the button, in Google Chrome, on OS X, I get the following errors in the console, the first due to the latter:
OPTIONS http://127.0.0.1:1337/an_endpoint/ 404 (Not Found) Objective-J.js:716
XMLHttpRequest cannot load http://127.0.0.1:1337/an_endpoint/.
Origin http://127.0.0.1:8080 is not allowed by Access-Control-Allow-Origin.
Which, is obviously due to the fact that my node server is at :1337, and my Cappuccino app is at :8080, which are technically different domains, due to the port part.
A bit of research led me to this post, which recommends considering the use of JSONP to inject remote scripts into the app. It sounds very messy, so I'd like to not go that route if not necessary.
So, my question is, how can I allow Cappuccino and Node.js to work together in harmony? It seems that if I can tell the Cappuccino app to use this ( header("Access-Control-Allow-Origin", "*"); ) header, all should be well, but I'm not sure how to do that. I tried having Node send that header, and it didn't seem to do anything.
You should use node to serve up the Cappuccino application so it's all on the same port.
The problem here is lack of configuration for CORS protection (Cross Origin Resource Sharing).
Somewhat simplified: The backend checks to see if the frontend is allowed to connect to the resource by checking to see if the request comes from the same server (protocol, domain, host, and port). in your case, the port is different and therefor the backend says NO and the frontend doesn't even actually perform the request. (This all happens in a preflight check).
In order to really solve this issue, you should learn about CORS but you really only need to do that if you plan to deploy something out of development. until then, you can just 'enable CORS' on your backend so it'll allow the frontend access:
var express = require( 'express' );
var cors = require( 'cors' );
var app = express();
app.use(cors);
app.get( '/an_endpoint', function(req, res){
res.send('Hello From Node Express!\n');
});
app.listen(1337);
This will allow all referers through to your code. Here are some more granular examples