We are facing CORS issue in Angular 6 using socket.io client when we are trying to connect to the server.
The error we are getting in the console of browser.
Access to XMLHttpRequest at 'http://********.com/socket.io/?EIO=3&transport=polling&t=N3jTiAZ' from origin 'http://localhost:4200' 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.
Here is the server code
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const server = require('http').createServer(app);
const conn = app.listen("3000")
const io = require('socket.io').listen(conn);
io.origins('*:*')
var connectioncheck = io.of('/check-connection');
connectioncheck.on('connection', function (socket) {
console.log('user connected');
});
Here is frontend code using simple html and js
<script src="https://cdn.jsdelivr.net/npm/socket.io-client#2/dist/socket.io.js"></script>
var socket = io.connect('http://********.com/check-connection');
socket.emit('connection', "hello",function(db){
console.log(db);
console.log("data from callback");
});
According to comments you gave above I think you should use NPM CORS in a way like this
let allowedOrigins = ["http://ServerA:3000", "http://ServerB:3000"]
let origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.header("Access-Control-Allow-Origin", origin); // restrict it to the required domain
}
Related
I cant figure why the cors express middleware wont work. cors, express, and ejs are all saved in package.json. The app works fine if I add corsanywhere proxy on the front end but id like to work around this on the server side. any help much appreciated I've been stuck on this.
the api is in the get View/index path
the error is:
Access to fetch at 'https://api.darksky.net/forecast/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
const express = require('express');
const app = express();
const ejs = require('ejs');
const cors = require('cors');
const PORT = process.env.PORT || 3000;
// app.use((req, res, next) => {
// res.header('Access-Control-Allow-Origin', '*')
// res.header('Access-Control-Allow-Headers', 'Origin', 'X-Requested-With')
// next();
// });
app.use(cors());
app.use(express.static(__dirname + '/Public'));
app.set('view engine', 'ejs');
app.get('/', cors(), (req, res) => {
res.render(__dirname + '/Views/index')
});
app.listen(PORT, () => {
console.log(`server is listening on ${PORT}`)
});
client side:
it works with the ${proxy} in there but id like to get rid of that
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(position => {
long = position.coords.longitude;
lat = position.coords.latitude;
var proxy = 'https://cors-anywhere.herokuapp.com/'
var api = `${proxy}https://api.darksky.net/forecast/042750f3abefefdfe2c9d43cf33ce576/${lat},${long}`;
fetch(api)
.then(response => {
return response.json();
})
.then(data => {
let {temperature, summary, icon,} = data.currently;
temperatureDegree.textContent = Math.floor(temperature);
temperatureDescription.textContent = summary;
locationTimezone.textContent = data.timezone;
setIcons(icon, document.querySelector('.icon'
w
``````
So, if you're trying to access some other service https://api.darksky.net/forecast/ (that you don't control) from your web page, then there is nothing you can do to make CORs work for that. It's up to the api.darksky.net server to decide if CORs is allowed or not. You can't change that.
You could make a request from your web page to your server to ask it to get some data from api.darksky.net for you and then return it back to your webpage (working as a simple proxy). Your server is not subject to any CORs limitations when accessing api.darksky.net. Only browsers are limited by CORs.
And, as you've found, you can also use a proxy service that enables CORs and fetches data for you.
Let's suppose you want to proxy the parts of the darksky API, you could do something simple like this:
const express = require('express');
const app = express();
const request = require('request');
const apiRouter = express.Router();
// maps /api/forecast/whatever to http://api.darksky.net/forecast/developerKey/whatever
// and pipes the response back
const apiKey = "yourAPIKeyHere";
apiRouter.get("/*", (req, res, next) => {
// parse out action and params
// from an incoming URL of /api/forecast/42.3601,-71.0589
// the /api will be the root of the router (so not in the URL here)
// "forecast" will be the action
// "42.3601,-71.0589" will be the params
let parts = req.path.slice(1).split("/"); // split into path segments, skipping leading /
let action = parts[0]; // take first path segment as the action
let params = parts.slice(1).join("/"); // take everything else for params
request({
uri: `https://api.darksky.net/${action}/${apiKey}/${params}`,
method: "get"
}).pipe(res);
});
app.use("/api", apiRouter);
app.listen(80);
Now, when you send this server, this request:
/api/forecast/42.3601,-71.0589
it will request:
https://api.darksky.net/forecast/yourAPIKeyHere/42.3601,-71.0589
and pipe the result back to the caller. I ran this test app and it worked for me. While I didn't see anything other than forecast URLs in the darksky.net API, it would work for anything of the format /api/someAction/someParams.
Note, you probably do NOT want to enable CORS on your server because you don't want other people's web pages to be able to use your proxy. And, since you're just sending requests to your own server now, you don't need CORS to be able to do that.
I'm using Express.js with the CORS middleware. I'm getting very strange behavior on Firefox v73.0.1 (64-bit)
Clean firefox profile... so nothing is cached.
I try a direct request to http://localhost/search?q=AMZN, I get results as expected.
I open my webapp which is running on localhost:3000. All of these requests are not using TLS/SSL.
I get "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/search?q=AMZN. (Reason: CORS request did not succeed)." when it tries to reach out to the API server backend.
I refresh the other tab where I was accessing localhost directly (same request which succeeded before), and I get a "connection reset".
Chrome does not do this...
I have been looking at wireshark and Firefox simply sends a GET request (several of them? Why?? I'm only making one), sends the headers and such, then it is followed by connection reset.
Sounds like node is doing something wrong? Or I dunno.
const express = require('express');
const fetch = require('node-fetch');
const util = require('util');
const app = express();
const port = 80;
var cors = require('cors')
var copts = {
origin: function (origin, callback) {
console.log('yeah');
// allow all
callback(null, true);
}
}
const SEARCH_URL = 'https://api.stocktwits.com/api/2/streams/symbol/%s.json';
app.get('/search', cors(copts), (req, res) => {
The "yeah" part never is hit at all.
Very simple clientside code.
return fetch(BACKEND_URL + uri).then(response => {
Tried removing CORS middleware and added these headers, based on examining github's cross-browser request-response in chrome
res.header('Access-Control-Allow-Methods', 'GET');
res.header('Access-Control-Max-Age', '3600');
res.header('Vary', 'Origin, Access-Control-Request-Headers, Access-Control-Request-Method, Accept-Encoding');
res.header('Access-Control-Allow-Origin', '*');
I didn't really have the options handler captured so maybe this didnt matter. I found those headers in the GET response.
It might be possible that the node server get crashed on an invalid reqeust and hence you are getting the reset error.
With cors package:
You need to add optionsSuccessStatus property in the cors options for some legacy browsers. And OPTIONS handler To enable pre-flightin requests.
const express = require('express');
const fetch = require('node-fetch');
const util = require('util');
const app = express();
const port = 80;
var cors = require('cors')
var copts = {
origin: function (origin, callback) {
console.log('yeah');
callback(null, true);
},
optionsSuccessStatus: 200
}
app.options("*", cors(copts));
const SEARCH_URL = 'https://api.stocktwits.com/api/2/streams/symbol/%s.json';
app.get('/search', cors(copts), (req, res) => { });
With headers.:
You are missing Access-Control-Allow-Headers in the response headers, you need to add the Access-Control-Allow-Headers header in the response header to allow the Access-Control-Allow-Origin header.
Try this.
const express = require('express');
const fetch = require('node-fetch');
const util = require('util');
const app = express();
const port = 80;
var cors = require('cors')
var copts = {
origin: function (origin, callback) {
console.log('yeah');
// allow all
callback(null, true);
}
}
const SEARCH_URL = 'https://api.stocktwits.com/api/2/streams/symbol/%s.json';
app.get('/search', (req, res) => {
res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin');
res.header('Access-Control-Allow-Origin', '*');
res.status(200).send("Ok")
});
in my case, FireFox removes the request header from ajax to a http url, but works fine with https
Have you updated your front end package.json file with the following?
"proxy": "http://localhost:[your port here]/",
try assigning CORS to the express server like so:
const cors = require('cors');
app.use(cors());
I’m using the MEAN stack (MongoDB, Express, Angular, and NodeJS).
There is a simple function to get data from an external API like this:
let api = 'https://thongtindoanhnghiep.co/api/city';
return this.http.get<any>(api).subscribe(res => { this.data = res; });
But whenever it sends a request, I get the following error:
"OPTIONS https://thongtindoanhnghiep.co/api/city 405 (Method Not Allowed)
Access to XMLHttpRequest at 'https://thongtindoanhnghiep.co/api/city' from origin 'http://localhost:4040' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
My Chrome has web security disabled, with the CORS extension installed, and my app is configured to enable CORS on the server side.
When I use Postman to do this, it is working well.
In node js you have fix this issue in 2 type
Type 1
install cors
npm install cors
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
// cors config
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT,DELETE");
res.header("Access-Control-Allow-Headers", "*");
next();
});
app.listen(8083, () => {
console.log('Server connected with 8083');
})
Type 2
npm install browser-sync --save
var fs = require('fs');
var http = require('http');
var https = require('https');
var privateKey = fs.readFileSync('node_modules/browser-sync/certs/server.key', 'utf8');
var certificate = fs.readFileSync('node_modules/browser-sync/certs/server.crt', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
httpServer.listen(8080,()=>{
console.log('Server connected with 8080');
});
httpsServer.listen(8081,()=>{
console.log('Server connected with 8081');
});
In that way you provide express middleware to the native http/https server
If you want your app running on ports below 1024, you will need to use sudo command (not recommended) or use a reverse proxy (e.g. nginx, haproxy).
You can use this in your Node.js application entry point
var cors = require('cors')
app.use(cors())
Or
You can use response object to set the header
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
Hopefully this should solve the problem.
I want to connect with socket.io to a backend that uses express.
the backend is used as api for other functionalities. So, I use some middleware to add headers to express (you could see that in the code).
the problem is that the socketio on the client side gives the following error:
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'.
but I need to keep the '*' to allow all users from any where to access my api.
var express = require('express'); var server = express();
var app = require('http').Server(server);
var io = require('socket.io')(app);
io.set( "Access-Control-Allow-Origin", "*" );
require('./controllers/watsonIoT.controller').startWatson(io);
server.use(function(request, response, next) { // configuration of headers
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Headers", "Content-Type, x-auth");
response.header("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT")
next();
})
.use('/gui', express.static('views'))
.use(bodyParser.json())
.use('/api', mainRouter)
.get('*', (req, res) => res.redirect('/'))
.listen(PORT,function(){
console.log("Starting ... port: "+ PORT);
// startWatson();
});
I am trying to display a dicom with NODEJS but the browser throws me this problem
XMLHttpRequest can not load http: // localhost: 8080 / wado?
RequestType = WADO & studyUID = 1.2.840.113704.1.111.5 ... 26513.429 &
contentType = application% 2Fdicom & transferSyntax =
1.2.840.10008.1.2. In 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http: // localhost: 3000' is
therefore not allowed access.
Then install npm the package cors
And here I leave my code part of my code app.js
Var express = require ('express');
Var cors = require ('cors')
App.use (cors ())
App.listen (3000, function () {
Console.log ('listening on 3000')
})
Also try adding this in app.js
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 ();
});
But the browser still displays the error:
XMLHttpRequest can not load http: // localhost: 8080 / wado?
RequestType = WADO & studyUID = 1.2.840.113704.1.111.5 ... 26513.429 &
contentType = application% 2Fdicom & transferSyntax =
1.2.840.10008.1.2. In 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http: // localhost: 3000' is
therefore not allowed access.
I have doubt because I also use the route index.js which I leave here
var express = require('express');
var router = express.Router();
var cors = require('cors')
/*var express = require('express');
var router = express.Router();*/
var mysql = require('mysql');
router.use(cors({origin: 'http://localhost:3000'}));
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
I'm sorry for my English
For security purpose browsers don't allow cross origin requests under normal conditions.
Your page is loading from localhost:3000, which defines the origin as it is the first request. Your code is trying to load data from another service running on port- 8080, that is different from origin. So basically you need to enable cors on the service running on port 8080 as it is the external source.