10

I have setup CORS on my node.js server on port 5000 as follows:

var app = express();

app.use(cors()); //normal CORS
app.options('*', cors()); //preflight 

app.post('/connect', function(req, res) { 
    console.log("Connection request received !")
});

var port = 5000;
app.listen(port, function () {
    console.log('Listening on port '+port);
});

I am now trying to send AJAX POST requests using JQuery like so, in a static web page open from my hard disk :

var xhr = $.post({
            url: 'http://localhost:5000/connect',
            complete: function() {
                console.log("done !")
            },
            crossDomain: true
        });

xhr.fail(function(xhr, status, error){
    alert(error)
})

The complete function is never called, and the only alert I get is an alert from the XHR fail handler, containing the following error :

NS_ERROR_DOM_BAD_URI: Access to restricted URI denied

I think CORS is well-configured, what am I missing ?


EDIT : for those in my case, the best solution I could find was to send the page from the server :

app.use(express.static('web'))

app.get("/", function(req, res) {
    res.sendFile(__dirname + '/web/HTML/index.html');
});
Magix
  • 3,557
  • 3
  • 18
  • 43
  • @PraveenKumar This question is NOT a duplicate of this one : http://stackoverflow.com/questions/7969265. The accepted answer there is to enable CORS to prevent problems with Cross-origin policy, which I did. Please try not to mark as duplicate too quickly. – Magix Sep 08 '16 at 08:45
  • Reopened it. Looks like a problem with the NodeJS stuff... Let's see if NodeJS folks answer it. – Praveen Kumar Purushothaman Sep 08 '16 at 08:46
  • 1
    Thank you very much – Magix Sep 08 '16 at 08:47
  • Do you by "in a static web page open from my hard disk" mean that the file is loaded using the `file://` protocol? – Phillip Sep 09 '16 at 14:52
  • @Philip absolutely – Magix Sep 09 '16 at 14:53
  • The issue definitively is that CORS does not work correctly. But I cannot reproduce the error, your example works fine here (with the versions of expressjs and cors that npm current installs). – Phillip Sep 09 '16 at 15:17
  • For info, my browser is firefox ESR 45.2.0 maybe this is where the problem comes from ? – Magix Sep 09 '16 at 15:29
  • have you tried a package addon like this one https://github.com/expressjs/cors – Tasos Sep 10 '16 at 16:57

4 Answers4

5

This is the code I am using. It is located in my app.js file

app.all("/*", function (req, res, next) {

  res.header("Access-Control-Allow-Origin", req.headers.origin);
  res.header("Access-Control-Allow-Credentials",true);
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Content-Type,Accept,X-Access-Token,X-Key,Authorization,X-Requested-With,Origin,Access-Control-Allow-Origin,Access-Control-Allow-Credentials');
  if (req.method === 'OPTIONS') {
    res.status(200).end();
  } else {
    next();
  }
});
frikkievb
  • 481
  • 2
  • 11
  • 1
    I am accepting your answer because, even though it doesn't directly solve the problem, it gives a good workaround until the `cors` module gets fixed. Also, the code is cleaner than @TimothyMoody's.Thank you ! – Magix Sep 16 '16 at 15:05
  • 2
    The `if ( req.method === 'OPTIONS')` saved me. Thanks!! – Lourens Jul 19 '17 at 12:52
1

I've never used cors() so I can't speak to that piece. But you could manually allow cross origin resource sharing by setting up the node.js headers.

Add This Pre-Route on All Requests

app.route('*')
   .all(function(req, res, next) {
     res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
     res.header('Access-Control-Allow-Origin', '*');
     res.header('Access-Control-Allow-Headers', 'X-API-TOKEN, Content-Type, Authorization, Content-Length, X-Requested-Wit
h');
   next();
})

This should work.

Timothy Moody
  • 361
  • 1
  • 4
  • 9
0

I have a project that use cors.

The node code used is just:

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

app.use(cors());

/* Connect/other routes here */

The jquery code look a litte different:

$.post('http://localhost:5000/connect', {}).done( () => {
  // Request complete
}).fail((jqXHR) => {
  // Request failed 
});
Joakim Ericsson
  • 4,256
  • 3
  • 19
  • 29
  • This is almost exactly equivalent to my code, except you don't enable pre-flight requests, and I don't use the `done` xhr callback ... – Magix Sep 16 '16 at 08:08
0

CORS doesn't work using the file protocol because there is no server there to send back the requisite headers. Your solution of using a server is the only way to get CORS to work.

Andrew Hedges
  • 21,058
  • 16
  • 62
  • 78
  • I want the server to send me the headers when AJAXing, not when loading the page, that's not how it works. When AJAXing, there is indeed a server which should send me the headers and it should be sufficient – Magix Sep 16 '16 at 08:07
  • Sorry, what I meant was that a page on the `file` protocol doesn't have a hostname to send in the Ajax request, so the responding server can't validate whether it matches the CORS access rules. – Andrew Hedges Sep 21 '16 at 16:51