I have a NodeJS app I am using as a game server.
I am trying to setup CORS with it, but app.use doesn't seem to be getting called.
Anyone know why?
var util = require("util"); // Utility resources (logging, object inspection, etc)
var fs = require('fs');
var express = require("express");
var app = express();
var port = 3000;
app.use(function (req, res, next) {
// these never get printed out:
util.log( "app.use adding Access-Control-Allow-Origin" );
console.log( "app.use adding Access-Control-Allow-Origin" );
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'https://example.com');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
var server = app.listen(port, function(){
console.log('CORS-enabled web server listening on port ' + port);
});
var io = require('socket.io').listen(server);
Checkout the npm cors package. https://www.npmjs.com/package/cors
Example usage where all requests will be CORS enabled:
var express = require('express')
, cors = require('cors')
, app = express();
app.use(cors());
app.get('/my_API_URL/:id', function(req, res, next){
res.json({msg: 'This is CORS-enabled for all origins!'});
});
app.listen(80, function(){
console.log('CORS-enabled web server listening on port 80');
});
On their page they also got other examples where the CORS are only enabled on a single route.
Also, just wondering how are you testing your application? You haven't defined any routes in the example code.
As pointed out in the comment section, #Nitzan Wilnai is not doing REST API, apologise for the confusion. It is suppose to be a simple server that listens on a certain port, so for this case you might not need express at all. Did some research and this solution came out;
io.configure('development', function(){
io.set('origins', '*:*');
}
OR
io.set( 'origins', '*domain.com*:*' );
References:
Socket.io doesn't set CORS header(s)
Just in case you are trying to build a chat program. Here is an example project;
https://github.com/socketio/socket.io
Related
I have an Express server as backend of my Dialogflow chatbot, when I access from the same host, I have no problem requesting the API, but when I access from the Firebase hosting whereI have my web App, I cannot request anything since the CORS headers are not being added, even though I added them.
This is the code:
// Sends static files from the public path directory
app.use(express.static(path.join(__dirname, '/Public')))
// Set Server Config
app.use(bodyParse.urlencoded({
extended: true
}));
app.use(bodyParse.json());
app.use(helmet.frameguard());
app.use(function (request, response, next) {
// Website you wish to allow to connect
// Request methods you wish to allow
response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
response.setHeader("Access-Control-Allow-Origin", 'https://newagent-249c5.web.app/');
// Pass to next layer of middleware
next();
});
// Configure Routes
app.use('/api', apiRoutes);
// Server index.html page when request to the root is made
app.get('/', function (request, response, next) {
response.sendFile('./Public/index.html');
});
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log("server listening at http://%s:%s", host, port);
});
This is cross-origin
This is the headers when I access from the same origin
For CORS most important is Access-Control-Allow-Origin header, and that client, who requesting, has host equal to value of this header. You can test things out pretty simple locally, spin up simple express server on, say, port 3000, and serve index.html with another server, express or nginx, on some other port. Then add request in index.html to first server, and try to fix CORS on this simple example.
I've angular cli project that hosted in azure and I'm making API call to different domain (in Zoho creator) so I have CROS issue I tried some solutions with no luck.
The error is
"Access to XMLHttpRequest at "https://xxxxxxx" from origin "https://yyyyyy" has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."
I use expressJS as my backend and I tried to add headers but it seems not working I don't know what I'm missing
APP.JS
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
// parse application/x-www-form-urlencoded
var cors = require('cors');
// Use this after the variable declaration
app.use(cors({origin: '*'}));
// parse application/json
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Angular DIST output folder
app.use(express.static(path.join(__dirname, 'dist')));
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:5000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
//Set Port
const port = process.env.PORT || '5000';
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`Running on localhost:${port}`));
I don't recognize exactly what It's happening but there's something that it makes me noise.
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:5000');
This code indicate that you can only receive requests from http://localhost:5000. Are you trying to consume it from http://localhost:5000? I don't think so because the port 5000 is being used by node.js. if you want to use it, you must set Access-Control-Allow-Origin to the Server or Site where you're trying consume it from.
Example, I have a application in Angular in my machine using the port 4200, so the request header should be:
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
Or, you can use * to allow everything but It's not secure.
res.setHeader('Access-Control-Allow-Origin', '*');
I'm having this weird problem with socket.io. I have an express app which I run on port 5000. I have configured socket.io like this:
const app = require('../index');
const http = require('http');
const server = http.Server(app);
const io = require('socket.io')(server);
io.on('connection', function (socket) {
console.log('User has connected');
socket.emit('connect', {
message: 'Hello World'
});
});
Then I import this piece of code into my index.js file like this:
const express = require('express');
const app = module.exports = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const request = require('request');
const boxRoutes = require('./routes/v1/boxRoutes');
const bidRoutes = require('./routes/v1/bidRoutes');
// use body parser so we can get info from POST and/or URL parameters
app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }));
app.use(bodyParser.json({ limit: '10mb' }));
require('./services/usersClass');
// cors set up
app.use(cors());
app.use(function (req, res, next) {
console.log('Headers Middleware Called');
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'origin, x-requested-with, content-type, accept, x-xsrf-token', 'token');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Request headers you wish to expose
res.setHeader('Access-Control-Expose-Headers', false);
next();
});
// Middleware to authenticate the requests to this service
app.use(function(req, res, next) {
console.log('Auth Middleware Called');
if(!req || !req.headers['authorization']) return res.sendStatus(401);
const token = req.headers['authorization'].split(' ')[1];
request.post(
'http://localhost:4000/api/v1/users/auth',
{
headers: {
'Authorization': `Bearer ${token}`
}
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
const data = JSON.parse(body);
res.locals.user = data.user;
next();
} else {
console.log('Request has failed. Please make sure you are logged in');
res.sendStatus(401);
}
}
);
});
app.use('/api/v1/boxes/', boxRoutes);
app.use('/api/v1/bids/', bidRoutes);
// disable 'powered by'
app.disable('x-powered-by');
app.listen(5000, () => {
console.log('Trading service is running on port 5000');
});
Now, in my client code, I try to establish socket.io connection when the user logs in. Everytime I try to connect to the server, I get the following error:
Failed to load
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=MA_9wXE:
Response to preflight request doesn't pass access control check: 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'. Origin 'http://localhost:3000' is therefore not allowed
access. The credentials mode of requests initiated by the
XMLHttpRequest is controlled by the withCredentials attribute.
I don't understand why the connection fails. I have configured Access-Control-Allow-Origin to my client domain but it still fails.
You can use cors npm module. It will fix your problem.
var cors = require('cors')
var app = express()
app.use(cors({origin: '*'}))
start '*' means allow every origins. You can type spesific origin too.
I've seen this problem before, but never seen it manifested as a cross origin issue. You are creating two separate http servers. One you are making your express server and the other you are making your socket.io server. The code you show only actually starts the express server and you show no code that actually starts your socket.io server.
Here's where you create these two separate servers:
const server = http.Server(app); // creates the http server you use for socket.io
app.listen(5000, () => {...}); // creates the http server you use with Express
Inside of app.listen(), it creates it's own new server and starts it. Your other server is never started (at least per the code you show here).
When you probably want to do is to make your socket.io server use the same server as your express server and then you should be able to connect just fine without any CORs issues.
If you want to use app.listen(), it will return the server object that it created and you need to use that to initialize socket.io.
If you want to use the other server, then you need to share that with your express initialization code so it can use that one.
I need to create a NodeJS application which serves only for exposing REST APIs. When I created a ExpressJS project using Express generator express myNodeApp, it creates a project defaulting the view to .jade files.
Can I create and run a NodeJS project without views ? My NodeJS project will expose REST services which another client application will consume. Hence my NodeJS project do not need any UI elements. Also what package.json or .bin/www file will have. I will be hosting my NodeJS project in Azure cloud and my client application will consume the exposed service from cloud.
For an example see the code in this answer:
Node.js send data to backend with AJAX
Stripping all unnecessary code it would be basically:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
app.post('/email', (req, res) => {
console.log(req.body.address);
res.json({ ok: true });
});
app.listen(4443, () => console.log('Listening on http://localhost:4443/'));
This code is a very simple REST API that exposes one endpoint but you can easily add more.
But if you're building a RESTful API from scratch then you can consider using some other frameworks like: Hapi, Restify, LoopBack, and other frameworks listed on http://nodeframework.com/ - Express is a very solid but fairly minimal framework and it's not the only option out there.
Yes you can. express is capable to return response other that html element.
However, I would recommend you to use swagger project in developing REST API via express. The project will surely come in handy when developing and MAINTAINING API, especially if your API is huge and complex (lots of url and operation).
This site has a good explanation on how to install, use and run the swagger in NodeJs.
You can do this with express - see below
Install express and body-parser, feel free to use the module below
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
module.exports = {
init: function(module_Enabled){
var portnum = 1234; process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var allowCrossDomain = 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.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
app.use(allowCrossDomain);
var server = app.listen(portnum, function() {
var host = server.address().address;
var port = server.address().port;
console.log("Content Provider Service listening at http://%s:%s", host, port);
});
app.get('/', function(req, res) {
res.send('data');
});
}
}
When running my application through Grunt serve on another machine although the application loads, the information from Mongo and node do not load:
Error message
Here is my server code:
//Loading requiriments
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var _ = require('lodash');
// Starting application
var app = express();
// Middleware for REST API
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(methodOverride('X-HTTP-Method-Override'));
// CORS (cross domain refference) Support
app.use(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.use('/hello', function(req, res, next) {
res.send('Hello Robin');
})
// connecting to MongoDB
mongoose.connect('mongodb://localhost/tvapp');
mongoose.connection.once('open', function() {
// Load models
app.models = require('./models/index');
// Load the routes.
var routes = require('./routes');
_.each(routes, function(controller, route) {
app.use(route, controller(app, route));
});
//log server action
console.log('Listening to port 3000');
// Listen on port defined
app.listen(3000, '127.0.0.1');
});
Does anyone have any idea on what I might have done wrong?
I am using yeoman as well, would that be an issue?
Also, on my machine works fine, it won't work on outside machines which have access to the application and the server separately however the application won't run the server
The IP host address you are using is localhost, i.e., 127.0.0.1. This IP is only available to the computer it is running on. For other computers to access your server, you will have to use another IP host. If it is on the same local network, you can use your LAN IP. If not, you will have to use your public IP. How you go about finding your LAN or public IP address will depend on your operating system.