jQuery:跨域AJAX调用导致"访问受限制的URI被拒绝"(代码1012)

Ron*_*ung 5 javascript ajax jquery json cors

我想要做的是在HTTP协议上有一个页面,将AJAX调用发送到同一个Web服务器,但使用HTTPS.请求页面和AJAX处理程序都在同一台服务器上,具有相同的域和端口.(即,唯一的区别是协议.)为了说明,

来自 http://www.example.com/index.php

触发对https://www.example.com/authenticate.php?user=123&password=456的jQuery AJAX调用

(我希望通过HTTPS传递密码,使其通过Internet加密.由于一些设计限制,我必须使用AJAX调用而不是重定向页面.)

我知道这里有一个CORS问题,因此我研究了一下,发现我实际上可以使用Access-Control-Allow-Origin标头来提供帮助.然后我在Apache的配置文件中设置以下内容,

Header set Access-Control-Allow-Origin *
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers "content-type, accept"
Header set Access-Control-Max-Age 1000
Run Code Online (Sandbox Code Playgroud)

我可以看到,当浏览器从服务器请求资源时,可以看到标题.请求:

Accept  */*
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Authorization   Basic Y2FzZXRhZ3JhbWRldjpwYXNzd29yZGRldiE=
Cache-Control   no-cache
Connection  keep-alive
Cookie  __utma=99230732.2019724749.1337107099.1337849971.1337856946.9; __utmz=99230732.1337107099.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=217650581.954519005.1337107174.1337772401.1337777327.5; __utmz=217650581.1337107174.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=99230732; PHPSESSID=m8lnqhqv2qa6f884a8um413n81
Host    www.example.com
Pragma  no-cache
Referer http://www.example.com/index.php
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0
Run Code Online (Sandbox Code Playgroud)

回答是这样的,

Accept-Ranges   bytes
Access-Control-Allow-Head...    content-type, accept
Access-Control-Allow-Meth...    GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Orig...    *
Access-Control-Max-Age  1000
Connection  close
Content-Length  16599
Content-Type    application/x-javascript
Date    Thu, 24 May 2012 14:48:17 GMT
Etag    "48157-40d7-4c0c938b220c0"
Last-Modified   Thu, 24 May 2012 14:39:39 GMT
Server  Apache/2.2.3 (CentOS)
Run Code Online (Sandbox Code Playgroud)

所以看起来标题部分已经完成.(我对吗?)

然后,当我尝试在JavaScript中调用以下jQuery AJAX代码时,

$.ajax({
    // Use HTTPS as there is password transferred
  url : "https://www.example.com/authentication.php",
  type : 'POST',
  dataType : 'json',
  async : false,
  data : ajaxData,
  beforeSend : function(xhr, opt) {},
  error : function(error) {
    console.log("Ajax error: unable to login user: ");
    console.log(error);
  },
  success : function(status) {
    if(status==USER_AUTH_AUTHENTICATE_USER_SUCCESS) {
      console.log("User login succeeded!");
    } else {
      console.log("User login failed.");
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

浏览器(FireFox 12)将只返回一个对象,

readyState 0
status 0
statusText "[Exception... "Access to restricted URI denied" code: "1012" nsresult: "0x805303f4 (NS_ERROR_DOM_BAD_URI)" location: "http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js Line: 8240"]"
Run Code Online (Sandbox Code Playgroud)

有什么东西我错过了吗?

事实上,我已经尝试过很多来自论坛和博客的建议,试图完成这项工作,但我仍然没有成功.我也试过使用JSONP,它在FireFox上工作正常但在Chrome/Safari上失败,没有可读的错误信息,只是从jQuery代码"head.insertBefore(script,head.firstChild);"中抛出一个错误.

如果有人能给我一些关于我的代码/设置有什么问题的线索,那就非常感激.

谢谢!

编辑于2012-05-25 20:29(UTC +08:00)

如我所知,我读了这个参考案例(http://stackoverflow.com/questions/5750696/how-to-get-a-cross-origin-resource-sharing-cors-post-request-working),我发现它已链接对于这种情况(http://stackoverflow.com/questions/5584923/a-cors-post-request-works-from-plain-javascript-but-why-not-with-jquery)也是相关的.我在那里尝试了样本XHR代码,

var request = new XMLHttpRequest();
var params = "action=something";
request.open('POST', 'https://www.example.com/controllers/Authentication.php', true);
request.onreadystatechange = function() {if (request.readyState==4) alert("It worked!");};
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);
Run Code Online (Sandbox Code Playgroud)

从具有HTTP协议的页面调用代码.代码执行后,会立即抛出以下错误,

访问受限制的URI被拒绝... test_xhr.php第11行

(如果我在JavaScript HTTP中更改HTTPS,则脚本会立即生效,因此不应出现任何语法问题.)

页面本身的请求和响应头如下.要求是,

Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Authorization   Basic Y2FzZXRhZ3JhbWRldjpwYXNzd29yZGRldiE=
Cache-Control   no-cache
Connection  keep-alive
Cookie  __utma=99230732.2019724749.1337107099.1337856946.1337921578.10; __utmz=99230732.1337107099.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=217650581.954519005.1337107174.1337772401.1337777327.5; __utmz=217650581.1337107174.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=99230732; PHPSESSID=ktd6anojfi40ohemlujosdmhi4
Host    www.example.com
Pragma  no-cache
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0
Run Code Online (Sandbox Code Playgroud)

回应是,

Access-Control-Allow-Head...    content-type, accept
Access-Control-Allow-Meth...    GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Orig...    *
Access-Control-Max-Age  1000
Connection  close
Content-Length  590
Content-Type    text/html; charset=UTF-8
Date    Fri, 25 May 2012 12:24:44 GMT
Server  Apache/2.2.3 (CentOS)
X-Powered-By    PHP/5.1.6
Run Code Online (Sandbox Code Playgroud)

所以我只是认为我的设置根本不对,但jQuery不是因为本机XHR不能正常工作.:(

Pet*_*tai 1

你有两个问题:

1) Access-Control-Allow-Origin “*”不适用于经过身份验证的调用,而不是 * 反映调用 Access-Control-Request-Origin 或 Origin 标头字段。

2) 您将需要响应中的 Access-Control-Allow-Credentials: true 。

其他可能有帮助的事情:手动设置授权标头、使用 base64 组装名称和密码。这是最可靠的工作方式。它的优点也是缺点:手动设置授权标头会激活基于 OPTIONS 标头的 CORS 握手。(您的所有请求之前都会有一个 OPTIONS 请求,您也必须处理该请求)这似乎在所有现代浏览器中都有一个一致的实现(IE9 当然是一个例外,但据称 IE10 可以工作)。

华泰