Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: Cross Domain AJAX Call Results in "Access to restricted URI denied" (Code 1012)

What I am trying to do is to have a page on the HTTP protocol sending an AJAX call to the same Web server but using HTTPS. Both the requesting page and the AJAX handler are on the same server, having the same domain and port. (I.e., only difference is the protocol.) To illustrate,

From http://www.example.com/index.php

Triggers a jQuery AJAX call to https://www.example.com/authenticate.php?user=123&password=456

(I am hoping to pass the password through HTTPS to make it encrypted over the Internet. Due to some design constraints I must use AJAX call instead of redirecting the page.)

I understand that there is a CORS issue here and thus I researched a bit and found that I could actually make use of the Access-Control-Allow-Origin header to help. I then set the following in my Apache's configuration file,

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

I can see that when the browser requests the resources from the server, the headers can be seen. Request:

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

The response is like,

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)

So it looks like the header part is fulfilled. (Am I right?)

Then when I tried to call the follow jQuery AJAX code in JavaScript,

$.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.");
    }
  }
});

The browser (FireFox 12) will just return an object,

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"]"

Is there something that I missed out?

In fact I had already tried a lot of suggestions from forums and blogs trying to get this done but still I am unsuccessful. I also tried using JSONP and it works fine on FireFox but failed on Chrome/Safari with no readable error message but just throwing an error from jQuery code "head.insertBefore( script, head.firstChild );".

Appreciate much if someone can give me a clue on what is wrong with my code/settings.

Thanks!

Edited on 2012-05-25 20:29 (UTC +08:00)

As suggested I read this reference case (http://stackoverflow.com/questions/5750696/how-to-get-a-cross-origin-resource-sharing-cors-post-request-working) and I found that it linked to this case (http://stackoverflow.com/questions/5584923/a-cors-post-request-works-from-plain-javascript-but-why-not-with-jquery) as well which is related. I tried the sample XHR code there,

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

The code is called from a page with HTTP protocol. Once the code is executed, the error below is thrown right away,

Access to restricted URI denied...test_xhr.php Line 11

(If I change the HTTPS in JavaScript HTTP, the script works right away and so there should not be any syntax problem or so.)

The request and response headers of the page itself are as follows. Request is,

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

The response is,

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

So I am just thinking something is fundamentally wrong with my setup but not jQuery as native XHR does not work as well. :(

like image 396
Ronald Yeung Avatar asked Nov 14 '22 05:11

Ronald Yeung


1 Answers

You have two issues:

1) Access-Control-Allow-Origin "*" is not working with authenticated calls, instead of * reflect the calls Access-Control-Request-Origin or Origin header fields.

2) You'll need Access-Control-Allow-Credentials: true in the response.

Other things that might help: setting authorization header manually, assembling name and password with base64. This is the surest way to have working. Its advantage is its drawback: setting authorization header manually activates the OPTIONS header based CORS handshake. (All your requests are preceded with an OPTIONS request that you have to also handle) This one seems to have a coherent implementation across all modern browsers (IE9 of course is an exception, IE10 however works allegedly).

HTH

like image 57
Peter Aron Zentai Avatar answered Nov 16 '22 02:11

Peter Aron Zentai