51

In summary I am using a viewer like api of dicom files called cornerstone, for this I connect to the WADO service of dc4chee to get the dicom, dcm4chee runs port 8080, and my application on node uses port 3000, so I am trying to show The browser's dicom.

https://www.npmjs.com/package/cornerstone-wado-image-loader

This is the error displayed by the browser

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.

In the documentation specified

Note that the web server must support Cross source resource sharing or the image will fail to load. If you are unable to get CORS enabled on the web server you are loading DICOM P10 instances from, you can use a reverse proxy. Here's a simple Node.js based on http-proxy that adds CORS headers that you might find useful.

And show this example code but I'm using express and this code does not work

Var http = require ('http'),
    HttpProxy = require ('http-proxy');

Var proxy = httpProxy.createProxyServer ({target: 'http: // localhost: 8042'}) .listen (8000);

Proxy.on ('proxyRes', function (proxyReq, req, res, options) {
  // add the CORS header to the response
  Res.setHeader ('Access-Control-Allow-Origin', '*');
});

Proxy.on ('error', function (e) {
  // suppress errors
});

Also use npm cors here the code

Var express = require ('express')
Var cors = require ('cors')
Var app = express ()
 
App.get ('/ products /: id', cors (), function (req, res, next) {
  Res.json ({msg: 'This is CORS-enabled for a Single Route'))
})
 
App.listen (80, function () {
  Console.log ('CORS-enabled web server listening on port 80')
})

But with this I enable the cors on port 3000 and not the 8080, I need the mode to activate or add 'Access-Control-Allow-Origin in headers response and not in header request,

How can I do to add CORS on port 8080 where dcm4chee runs from NODEjs?

update!

The server responds with the following;

RESPONDE HEADER

Content-Type:application/dicom
Date:Sat, 01 Apr 2017 01:15:38 GMT
Expires:0
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked
X-Powered-By:Servlet 2.4; JBoss-4.2.3.GA (build: SVNTag=JBoss_4_2_3_GA 
date=200807181439)/JBossWeb-2.0

REQUEST HEADER

Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:es-ES,es;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Host:localhost:8080
Origin:http: //localhost:3000
Referer:http: //localhost:3000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/55.0.2883.87 Safari/537.36

HOW TO ENABLE THE CORS IN RESPONSE HEADER??

Nimantha
  • 6,405
  • 6
  • 28
  • 69
M. Node
  • 703
  • 1
  • 6
  • 15
  • 4
    Does this code actually start a server? You have several syntax errors... `Var` cannot be capitalized, and you are capitalizing variable names (which are case-sensitive) like using `App` but you defined it as `app`. – AJ Funk Mar 31 '17 at 21:49
  • Possible duplicate of [No 'Access-Control-Allow-Origin' - Node / Apache Port Issue](https://stackoverflow.com/questions/18310394/no-access-control-allow-origin-node-apache-port-issue) – Patrick Roberts Jun 07 '17 at 05:55
  • 1
    Possible duplicate of [How to allow CORS?](https://stackoverflow.com/questions/7067966/how-to-allow-cors) – zguesmi Aug 16 '17 at 15:53
  • Have a look https://stackoverflow.com/a/46024491/4902660 – Tal Aug 29 '19 at 07:33
  • Looking at `App.get ('/ products /: id', cors (), function (req, res, next) { Res.json ({msg: 'This is CORS-enabled for a Single Route')) })` - `Res` and `res` are not the same variable – John Jun 25 '21 at 08:11

9 Answers9

80

do

npm install cors --save

and just add these lines in your main file where your request is going.

const cors = require('cors');
const express = require('express');
const app = express();
app.use(cors());
Phil
  • 157,677
  • 23
  • 242
  • 245
Yatender Singh
  • 3,098
  • 3
  • 22
  • 31
  • 1
    This is the answer -- preflight requests use OPTIONS verbs in HTTP, and `.options()` handles those verbs. – O. Jones Dec 16 '20 at 13:40
  • 1
    @O.Jones When using cors as a global middleware with `app.use(cors());` you don't need to also assign it `OPTIONS` requests. See the note here: http://expressjs.com/en/resources/middleware/cors.html#enabling-cors-pre-flight – Basti Sep 27 '21 at 09:51
12

Adding CORS(Cross-Origin-Resource-Sharing) to your node, express app is quite easy...

You need to install cors library via npm first, using the command below:

npm install cors -S

and if you need it globally, just add -g flag to it...

Then in your express app, do this:

const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());

Also these are other examples for cors from their doc:

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

app.get('/products/: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')
})

Configuring CORS Asynchronously:

var express = require('express')
var cors = require('cors')
var app = express()

var whitelist = ['http://example1.com', 'http://example2.com']
var corsOptionsDelegate = function (req, callback) {
  var corsOptions;
  if (whitelist.indexOf(req.header('Origin')) !== -1) {
    corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
  }else{
    corsOptions = { origin: false } // disable CORS for this request
  }
  callback(null, corsOptions) // callback expects two parameters: error and options
}

app.get('/products/:id', cors(corsOptionsDelegate), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a whitelisted domain.'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})
Alireza
  • 100,211
  • 27
  • 269
  • 172
  • 1
    I am bit late here, with latest express Router is a separate module which we will have to rely. So, how to apply cors to async routes? **Ex:** `router.get('/', cors(corsOptions), async (req, res ) => res.json('test')`? – Mithun Shreevatsa Aug 23 '19 at 07:55
  • @MithunShreevatsa Express never uses the return value of any middleware or route handler so it does not matter if they are async or not – Phil May 25 '23 at 00:44
10

To enable cors you can do this:

var cors = require('cors');
app.use(cors());
// to change your ports for different cors stuff:
app.set('port', process.env.PORT || 3000);
app.listen(app.get('port'), function() { 
  console.log('we are listening on: ', 
  app.get('port'))
});

Remember that cors are middleware, so you will want to have app.use before it so that your incoming requests will go through cors before they hit your routes.

You can change the ports depending on which one you want to use. I am pretty sure you can also replace the || with && to listen on multiple ports and set cors on those.

In raw node, I believe you have to use the writeHead, but I am not sure about the raw node implementation.

hisener
  • 1,431
  • 1
  • 17
  • 23
JonathanMitchell
  • 400
  • 1
  • 2
  • 12
  • My problem comes from port 8080, as I add Access-Control-Allow-Origin to port 8080 which is where the dcm4chee service works which provides me the DICOM files, my application works on port 3000 and already enable the cors in the port 3000, but as I enable the CORS in port 8080 where the service that provides the DICOM images works, that is my question. – M. Node Apr 01 '17 at 00:01
9

The error displayed by the browser means, server localhost:8080 refused a request from localhost:3000, It seems cors didn't set well on server localhost:8080.

The response header should have something like this:

Access-Control-Allow-Headers:Content-Type,Content-Length, Authorization, Accept,X-Requested-With
Access-Control-Allow-Methods:PUT,POST,GET,DELETE,OPTIONS
Access-Control-Allow-Origin:*

Try add cors header in your 8080 server.

app.all('*', function (req, res) {
 res.header("Access-Control-Allow-Origin", "*");
 res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
 res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
 //...
});
Kerem Baydoğan
  • 10,475
  • 1
  • 43
  • 50
cxxsn
  • 190
  • 6
  • Is it my problem on port 8080 dcm4chee works, how do i add that? How do I configure that from my application that works on port 3000? – M. Node Apr 01 '17 at 01:43
  • There is no need to config cors on port 3000, page is served on 3000. The situation here is browser open a page on 3000, then request an api served on 8080. So, server 8080 need set to allow cross origin request. – cxxsn Apr 01 '17 at 01:48
  • Could you recommend an api for that? please – M. Node Apr 01 '17 at 01:53
  • 1
    just use `app.use(cors());` on server 8080. – cxxsn Apr 01 '17 at 02:10
  • It is what is what I do not understand, sorry for ignorance, but since I am working with NODEJS and my application is in port 3000, and the DCM4CHEE IS IN PORT 8080, I can not converge CORS from my application of the port 3000 , How do I do that for the port 3000 application configure the 8080 port CORS WHICH IS USED BY DCM4CHEE WHICH IS THE DICOM PROVIDER? I do not know if I explain well, sorry = (probe with app.use (cors ({source: 'localhost: 8080';}));) in app.js of my application with port 3000 – M. Node Apr 01 '17 at 02:33
  • and only activates CORS IN PORT 3000, AND NOT IN PORT 8080, is what I am trying to say, how active the CORS of port 8080 from my application NODEJS who runs in PORT 3000? I'm sorry, my English is bad, I hope you can understand me – M. Node Apr 01 '17 at 02:33
  • My app.js code var express = require('express'); var cors = require('cors') var users = require('./routes/users'); var app = express(); app.use(cors({origin: 'http://localhost:8080'})); app.set('views', path.join(__dirname, 'views')); app.use('/', index); app.use('/users', users); app.listen(3000, function() { }); module.exports = app; – M. Node Apr 01 '17 at 02:44
  • Seems you may miss some point of [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS).If you activates CORS in port 3000, this means page served on other server can request localhost:3000, let's say if you have a restful api like `/getSomeInfo` on port 3000 server. and then start a new server at port 8888, serve some html files, open browser and visit localhost:8888/test.html, the test.html can request `localhost:3000/getSomeInfo`. – cxxsn Apr 01 '17 at 03:10
  • If `only activates CORS IN PORT 3000, AND NOT IN PORT 8080`, a page served on 3000 server, can not request 8080 server. Actually, there should be `only activates CORS IN PORT 8080, AND NOT IN PORT 3000`. If can not modify server 8080, you can set a middle proxy server, e.g. localhost:8000, and set this server allow CORS request. Then, page from localhost:3000 in browser request localhost:8000, localhost:8000 request localhost:8080, and send the response to localhost:3000. CORS request block is happen in browser, not server. – cxxsn Apr 01 '17 at 03:19
7

CORS didn't work on localhost until I added http:// to request url

Not working localhost:3001

Working fine http://localhost:3001

This is what my working code looks at the end

Node side

var cors = require('cors')
const app = express();
app.use(cors()); // Make sure this line comes right after express()

Front-end side

let response = await axios.post("http://localhost:3001/uploadFile", formData); 
// the http:// is required cors to work for localhost
Nika Tsogiaidze
  • 949
  • 14
  • 18
3

This code is helped me to resolve the resources cors issue with the express. And You can use other options easily with the asynchronous origin configuration.

var cors = require('cors'); //import cors module

var whitelist = ['http://localhost:8000', 'http://localhost:8080']; //white list consumers
var corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true);
    } else {
      callback(null, false);
    }
  },
  methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'],
  optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
  credentials: true, //Credentials are cookies, authorization headers or TLS client certificates.
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'device-remember-token', 'Access-Control-Allow-Origin', 'Origin', 'Accept']
};

app.use(cors(corsOptions)); //adding cors middleware to the express with above configurations
Harsha Basnayake
  • 4,565
  • 3
  • 17
  • 23
3

To solve this problem first of all you have to understand what Access-Control-Allow-Origin: The value for this Header will be the host from where you will send a request to your server ( eg express ).

Step 1: allow cors on the server side, (to allow cross origin request you can use * instead of http://localhost:3000:

var express = require("express");
var app = express();
 
 
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

Step 2: just use your http client , I am using Axios:

var qs = require("querystring");
var axios = require("axios");
const sendEmail = (email, subject, template) => {

    var data = qs.stringify({
        email: email,
        subject: subject,
        template: template,
    });
    var config = {
        method: "post",
        url: "https://abc-domain.com/endpoint",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded",
        },
        data: data,
    };

    axios(config)
        .then(function(response) {
            console.log(JSON.stringify(response.data));
        })
        .catch(function(error) {
            console.log(error);
        });
};

module.exports = sendEmail;
Rashid Iqbal
  • 1,123
  • 13
  • 13
0
//Définition des CORS Middleware 
app.use(function(req, res, next) {
    res.setHeader("Access-Control-Allow-Headers", "X-Requested-With,content-type, Accept,Authorization,Origin");
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
    res.setHeader("Access-Control-Allow-Credentials", true);
    next();
  });`enter code here`
0

I also met this issue. To solve it I used CORS module and imported it into my routings:

import cors from 'cors';
const router = new Router();
router.get('/posts', cors(), PostController.getAll);
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
DimtryKab
  • 1
  • 1