akronymn
akronymn

Reputation: 2446

How can I send an AJAX request to a node.js server via HTTPS?

I have the following node.js server set up listening to port 9001

var https = require('https');  
var fs = require('fs');  
var qs = require('querystring');    
var options = {  
  key: fs.readFileSync('privatekey.pem'),  
  cert: fs.readFileSync('certificate.pem')  
};  
https.createServer(options, function (req, res) {  
  res.writeHead(200);  
  console.log('Request Received!');  
  console.log(req.method);  
  if (true || req.method == 'POST') {  
    var body = '';  
    req.on('data', function (data) {  
      body += data;  
    });  
    req.on('end', function () {  
      console.log(body);  
      var POST = qs.parse(body);  
      console.log(POST);  
    });  
  }  
  res.end("hello, world\n");  
}).listen(9001);

and I am trying to get this server to respond to an AJAX call

function form_save()  
{  
  console.log("submitted!");  
  var data_obj = {  
    data1: "item1",  
    data2: "item2"  
  }  
  $.ajax({  
    url: 'https://adam.testserver.com:9001/',  
    type: "POST",  
    dataType: "json",  
    data: data_obj,  
    success: function() {  
      console.log("success!");  
    },  
    complete: function() {  
      console.log("complete!");  
    }  
  });  
}

There are two problems occurring with my arrangement. The first is that if I start the server and then click the button that triggers my form_save() the node server does not respond and I get the following error:

submitted!
OPTIONS https://adam.testserver.com:9001/ Resource failed to load
jQuery.extend.ajaxjquery.js:3633
$.ajaxjquery.validate.js:1087
form_savew_worksheet.php:64
confirm_deletew_worksheet.php:95
jQuery.event.handlejquery.js:2693
jQuery.event.add.handlejquery.js:2468
w_worksheet.php:73
complete!

At this point if I access that url directy (https://adam.testserver.com:9001/) I get the expected "hello, world" output as well as the console message "Request Received! GET". From this point on if I click the button to trigger my AJAX call I get a new error.

submitted!
XMLHttpRequest cannot load https://adam.testserver.com:9001/. Origin
https://adam.testserver.com is not allowed by Access-Control-Allow-Origin.
w_worksheet.php:73
complete!

I don't understand why I get this message as both my form and node server reside on the same server. Thanks for taking the time to read, I appreciate any help I can get on this. I've been stuck for a while now!

Upvotes: 0

Views: 4195

Answers (1)

user1207456
user1207456

Reputation:

You've run into the Cross-Origin Resource Sharing (CORS) specification.

Note the OPTIONS in your output. The OPTIONS HTTP Verb is used by the browser to query the web server about the URL, not to GET its contents or POST data to it.

Your server doesn't respond with the correct header data on a CORS request, so your browser assumes it has no rights to access the data, and refuses to GET or POST to the URL.

If you truly want to let any website in the world run that AJAX request, you can do something similar to the following:

function handleOptions(request, response) {
    response.writeHead(200, {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Method": "POST, GET, OPTIONS",
        "Access-Control-Allow-Headers": request.headers["access-control-request-headers"]
    });
    response.end();
}

function server(request, response) {
    if(request.method == "POST") {
        handlePost(request, response);
    } else if(request.method == "OPTIONS") {
        handleOptions(request, response);
    } else {
        handleOther(response);
    }
}
https.createServer(sslObj, server).listen(9001);

You can fill in the details and whether you should handle GET separately, and so on (handleOther should return an appropriate error code for each request method you don't support).

Upvotes: 2

Related Questions