Please help check CORS issue in Firefox jQuery ajax when 401

It makes me think.

jQuery 1.4.2, Windows XP sp3

Here is my test.

Download firefox 3.5+

http://plungjan.name/test/testcors.html

work

Save the file to your hard drive and run from there

From my office, external work and internal not

It is also interesting that I cannot work at a time.

Background: I use GET for an internal web service that uses CORS . Please DO NOT post any responses stating that FF does not handle cross-domain requests when it does this from v3.5, as described in detail here and here

It works in IE8 and FF3.6.6 from one server to another, and now almost from the file system (file: ///) to the service. Only from the file system and only when FF 3.6.6 needs to be agreed (the user has already registered, logged in and sent credentials!) To not receive data after negotiations. jQuery xhr returns status 0 and there is no data / responseText or something else It seems to me that jQuery reacts and saves xhr from 401, not from 200 OK later

Here is the result that I get at the end of the message when I warn the XHR object:

Status:success Data:[] XHR: some native functions, readyState:4 status:0 responseXML:null responseText: withCredentials:true 

if I make a call to the same server but without credentials, the data is returned only in a thin cross-domain

So the message is as follows:

 GET /restapplicationusingcors/authenticationneeded-internal/someid Accept: application/json Accept-Language: en . . Origin: null Cookie: LtpaToken=... 

is returning

 HTTP/1.1 401 Unauthorized Server: Apache Pragma: No-cache Cache-Control: no-cache Expires: Thu, 01 Jan 1970 01:00:00 CET WWW-Authenticate: Negotiate Connection: close Transfer-Encoding: chunked Content-Type: text/html 

Then ff sends

 GET /restapplicationusingcors/authenticationneeded-internal/someid HTTP/1.1 Host: myhost.myintranet.bla User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 Accept: application/json Accept-Language: en Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Origin: null Cookie: LtpaToken=.... Authorization: Negotiate .... 

and is rewarded with the file that I need, but cannot get into FF:

 HTTP/1.1 200 OK Date: Tue, 20 Jul 2010 12:08:39 GMT Pragma: No-cache Cache-Control: no-cache, max-age=600, s-maxage=3600 Expires: Thu, 01 Jan 1970 01:00:00 CET X-Powered-By: ... Content-Disposition: inline;filename=nnnnnn.json Content-Language: en Access-Control-Allow-Origin: ... Keep-Alive: timeout=6, max=70 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: application/json;charset=UTF-8 

DATA SENT FROM THE SERVER NOT IN THE XHR OBJECT

Here is my code

 function getJSON(url,func,lang) { accept = 'application/json'; lang=lang?lang:"*"; // gruesome hack to handle that APPENDS the mime header to */* !!! // NOW HANDLED by first setting Accept to "" !!! // if ($.browser.msie && url.indexOf('serveAsMime')==-1) { // url+= '?serveAsMime='+accept; // } if (currentRequest != null) currentRequest.abort(); var requestObjectJSON = { url : url, // dataType: "json", method : 'get', beforeSend: function(xhr){ xhr.setRequestHeader('Accept', ""); // IE hack xhr.setRequestHeader('Accept', accept); xhr.setRequestHeader('Accept-Language', lang); if (url.indexOf('-internal') !=-1) { try { xhr.withCredentials = true; alert('set credentials') } catch(e) { alert('cannot set xhr with credentials') } } }, success: function(data,status,xhr) { var responseText = xhr.responseText; var responseJSON = xhr.responseJSON; var t = ""; try{ for (var o in xhr) t += '\n'+o+':'+xhr[o]; } catch(e) { if (e.message.indexOf('.channel')==-1)alert(e.message); } alert('Status:'+status+'\nData:['+data+']\nXHR:'+t); func(responseText); }, } currentRequest = $.ajax(requestObjectJSON); } 
+6
json javascript jquery authentication cors
source share
4 answers

This is a hit in the dark, as I do not fully understand your problem, but I think you might have a problem with file: URLs that are not considered to be of any origin. I'm not sure if CORS can even be resolved from the file url.

+3
source share

So, you need to install ajax prefilter in your model / collection in order to use CORS. Otherwise, it does not send a cookie.

 $.ajaxPrefilter( function( options, originalOptions, jqXHR ) { options.xhrFields = { withCredentials: true }; }); 

I put this in my Model / Collection initialization function.

+1
source share

These are the conditions that must be met to get CORS to work with secure services:

  • The service response should contain the header Access-Control-Allow-Credentials: true (see Requests with credentials and You cannot use a wildcard in Access-Control-Allow-Origin when the credential flag is correct ).
  • Access-Control-Allow-Origin response header should not be * . The idea is to return the value passed by the client in the Origin header (see Examples in this post ).
  • According to the specification, the OPTIONS method should return an HTTP 200 code, so it cannot be protected (see CORS ).
  • For PUT / POST methods that must pass specific request headers for service (e.g. Content-Type or Accept ), these headers must be listed in Access-Control-Allow-Headers (see jQuery AJAX does not work if headers are specified )
  • JavaScript must set this XMLHttpRequest property: xhr.withCredentials = true; (as Kirby answered)

General configuration for Apache:

 # Static content: SetEnvIf Request_URI ".*" no-jk # RESTful service: SetEnvIf Request_URI "^/backend/" !no-jk SetEnvIf Request_Method "OPTIONS" no-jk # Fallback value: SetEnv http_origin "*" SetEnvIf Origin "^https?://(localhost|.*\.myconpany\.org)(:[0-9]+)?$" http_origin=$0 Header set Access-Control-Allow-Credentials "true" Header set Access-Control-Allow-Origin "%{http_origin}e" Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE" Header set Access-Control-Allow-Headers "Content-Type, Accept" JkMount /* loadbalancer 
+1
source share

CORS with file://

If you have problems resolving the origin from the file:// protocol, in accordance with the Web Development Concept , this should be done just like any other origin. I could not find information about browser support, but I think that every browser that supports CORS also supports this one.

The concept of Web Origin talks about the file URI scheme:

  4. If uri-scheme is "file", the implementation MAY return an implementation-defined value. NOTE: Historically, user agents have granted content from the file scheme a tremendous amount of privilege. However, granting all local files such wide privileges can lead to privilege escalation attacks. Some user agents have had success granting local files directory-based privileges, but this approach has not been widely adopted. Other user agents use globally unique identifiers for each file URI, which is the most secure option. 

According to wikipedia, the domain according to the file URI scheme is localhost. It is not indicated by the address bar, but I do not think that this is possible in the permitted source headers. Therefore, if your browser implementation allows the creation of a file using the URI, you must add file://localhost to your permitted origin, and after that everything should work correctly.

Here's how it should work, now you can meet reality:

  • I tested the current firefox 29.0.1 and it did not work. However, the file:// protocol is mapped to null this implementation. Thus, firefox works null . I tried a wider list of domains, but I was not able to resolve multiple domains. It seems that firefox does not support a list with multiple domains at the moment.
  • I tested with chrome 35.0.1916, it works the same as firefox.
  • I tested with msie 11.0.9600. When requested from the file protocol, the allow blocked content button is always displayed, even if you do not specify a zero origin. For other domains, it works the same as previous browsers.

HTTP basic auth:

The part of the credentials that I tried using PHP and HTTP basic auth.

http: //test.loc
Displays :-) when entering the system and :-( for unauthorized access.

 <?php function authorized() { if (empty($_SERVER['PHP_AUTH_USER']) || empty($_SERVER['PHP_AUTH_PW'])) return false; return ($_SERVER['PHP_AUTH_USER'] == 'username' && $_SERVER['PHP_AUTH_PW'] == 'password'); } function unauthorized() { header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Basic realm="Restricted Area"'); echo '<a href="http://test.loc">:-(</a>'; } if (!isset($_GET['logout']) && authorized()) { echo '<a href="http://test.loc?logout=1">:-)</a>'; } else unauthorized(); 

Thus, this code changes the location by logging in and logging out.

Cross-Domain CORS with HTTP Basic

http: //todo.loc
Gets the contents of http: //test.loc with the XHR cross-domain and displays it.

 cross domain ajax<br /> <script> var xhr = new XMLHttpRequest(); xhr.open('GET', "http://test.loc", true); xhr.withCredentials = true; xhr.onreadystatechange = function (){ if (xhr.readyState==4) { document.body.innerHTML += xhr.responseText; } }; xhr.send(); </script> 

Requires http: //test.loc headers :

 Access-Control-Allow-Origin: http://todo.loc Access-Control-Allow-Credentials: true 

CORS Cross Schema with HTTP Basic

File: ///path/x.html
Retrieves the contents of http: //test.loc with an XHR cross- section and displays it.

 cross scheme ajax<br /> <script> var xhr = new XMLHttpRequest(); xhr.open('GET', "http://test.loc", true); xhr.withCredentials = true; xhr.onreadystatechange = function (){ if (xhr.readyState==4) { document.body.innerHTML += xhr.responseText; } }; xhr.send(); </script> 

Requires http: //test.loc headers :

 Access-Control-Allow-Origin: null Access-Control-Allow-Credentials: true 

Output:

I tested the CORS cross-sim with the credentials called from file:// and it works fine in firefox, chrome and msie.

0
source share

All Articles