0

Working on that problem, I wrote the following script:

window.onload = function() {
    var request = new XMLHttpRequest();
    var url = "http://localhost:3000/say_hello";
    var params = "username=FooMan";

    request.onreadystatechange = function() {
        if (request.readyState == 4 && request.status == 200) {
            console.log(request.responseText);
        }
    }
    request.open("POST", url, true);
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    request.withCredentials = true;
    request.send(params);
}

However every time I try to execute that script I'm getting

XMLHttpRequest cannot load http://localhost:3000/say_hello. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

I've tried using

 request.setRequestHeader("Access-Control-Allow-Origin", "*");
 request.setRequestHeader("Access-Control-Allow-Origin", "hello.html");

The browser is Chrome. What am I doing wrong or missing?

AlliterativeAlice
  • 11,841
  • 9
  • 52
  • 69
cybertextron
  • 10,547
  • 28
  • 104
  • 208

2 Answers2

0

The Access-Control-Allow-Origin header needs to be set on the server side and sent in the response, not set on the client side in the request. In Rails this can be achieved by placing the following code in your controller:

headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'

For more information see Allow anything through CORS Policy

AlliterativeAlice
  • 11,841
  • 9
  • 52
  • 69
0

You are running into a same-origin security limitation. By default, Javascript is not allowed to send Ajax calls to servers that have a different origin (domain, port and protocol) than the web page that the script is running in.

In your particular case, this part of your error message:

Origin 'null' is therefore not allowed access.

Indicates that you are probably running a local web page (one on your hard drive) and the script is being blocked from accessing an external server via Ajax.

If the webpage the script is in is running on an actual web server (not from your local hard drive), then, by default, Ajax calls can be made only to that same web server. If you want to make Ajax calls to other servers, then you need a cooperating server in order to communicate with that other server.

To make a plain Ajax call, the server would have to specify Access-Control-Allow-Origin headers that tell the host browser that it is OK to accept Ajax calls from some domains other than the server itself. This is referred to as CORS (cross origin resource sharing). You can read a lot more about how to use CORS here on MDN. You cannot set these headers from the client - they must be set from the server. It is the server that must grant the browser permission to have cross site access, not the other way around.

In addition to CORS, JSONP is also a work-around for cross site access.

Both CORS and JSONP require cooperation from the host server to allow the cross origin access. And, even if using CORS or JSONP, some browsers (like Chrome) will still block the access if the web page is running from the local file system (not on an actual web server). This limitation can be temporarily bypassed in Chrome with a command line option before running the browser for development purposes, but that is not obviously a general purpose solution.

jfriend00
  • 683,504
  • 96
  • 985
  • 979