使用XMLHttpRequest发布到页面

时间:2015-05-09 01:45:46

标签: javascript ruby-on-rails json http post

解决这个问题,我编写了以下脚本:

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);
}

然而,每当我尝试执行该脚本时,我都会

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.

我尝试过使用

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

浏览器为Chrome。我做错了什么或错过了什么?

2 个答案:

答案 0 :(得分:0)

Access-Control-Allow-Origin标头需要在服务器端设置并在响应中发送,而不是在请求中的客户端设置。在Rails中,可以通过将以下代码放在控制器中来实现:

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'

有关详细信息,请参阅Allow anything through CORS Policy

答案 1 :(得分:0)

您遇到了同源安全限制。默认情况下,不允许Javascript向具有与运行脚本的网页不同的源(域,端口和协议)的服务器发送Ajax调用。

在您的特定情况下,这部分错误消息:

Origin 'null' is therefore not allowed access.

表示您可能正在运行本地网页(硬盘驱动器上的网页),并且正在阻止脚本通过Ajax访问外部服务器。

如果脚本所在的网页在实际的Web服务器上运行(而不是从本地硬盘驱动器),则默认情况下,只能对同一个Web服务器进行Ajax调用。如果要对其他服务器进行Ajax调用,则需要一个协作服务器才能与其他服务器通信。

要进行普通的Ajax调用,服务器必须指定Access-Control-Allow-Origin标头,告诉主机浏览器可以接受来自服务器本身以外的某些域的Ajax调用。这称为CORS(跨源资源共享)。您可以阅读有关如何使用CORS here on MDN的更多信息。您无法从客户端设置这些标头 - 必须从服务器设置它们。服务器必须授予浏览器访问跨站点权限的权限,而不是相反。

除了CORS之外,JSONP也是跨站点访问的解决方法。

CORS和JSONP都需要来自主机服务器的协作才能允许跨源访问。而且,即使使用CORS或JSONP,如果网页从本地文件系统(而不是在实际的Web服务器上)运行,某些浏览器(如Chrome)仍会阻止访问。在运行浏览器以进行开发之前,可​​以使用命令行选项在Chrome中临时绕过此限制,但这显然不是通用解决方案。