Cross Origin Resource Sharing with PrototypeJS

13,571

Solution 1

I'm having the same problem. The link @mplungjan shared contains the answer :

You simply have to let the browser know that the x-json header is safe by using the access-control-expose-headers

I'm using this line in Ruby on Rails controller

  headers['Access-Control-Expose-Headers'] = 'x-json'

(This should be quite easy to translate into other programming languages :) )

More details on this page

Solution 2

Please have a look at PREFLIGHT here https://developer.mozilla.org/En/HTTP_access_control

Your issue is that Fx is reacting to the custom headers (X-...) and will trigger preflighting. You will need to have the server return all access-control headers for OPTIONS and POST and have it allow custom headers.

Solution 3

I found solution on other SO question. And it works for me -- details are here.

To sum up -- you need onCreate event in your Ajax.Request which removes non-standard headers:

    onCreate: function(response) { // here comes the fix
        var t = response.transport; 
        t.setRequestHeader = t.setRequestHeader.wrap(function(original, k, v) { 
            if (/^(accept|accept-language|content-language)$/i.test(k)) 
                return original(k, v); 
            if (/^content-type$/i.test(k) && 
                /^(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)(;.+)?$/i.test(v)) 
                return original(k, v); 
            return; 
        }); 
    }
Share:
13,571
Hans Sperker
Author by

Hans Sperker

I’m a Software-Engineer and Architect (mostly backend) employing Domain Driven Design where possible and like working in an agile user centric manner. I’m a perpetual learner and like solving nontrivial technical problems e.g. by researching and first principle thinking. I like to help a team grow and grow in a team. I’m interested in areas like distributed systems, high performance and low latency systems and computer vision / object recognition.

Updated on June 04, 2022

Comments

  • Hans Sperker
    Hans Sperker about 2 years

    I am having some trouble with Cross Origin Resource Sharing and Prototype. I have a simple post request to a foreign resource, and for a simple post request there are some rules that must be satisfied:

    the Content-Type must be on of application/x-www-form-urlencoded, multipart/form-data, or text/plain, a simple request does not set custom headers with the http Request, and the Server must set the Access-Control-Allow-Origin header correct.

    with a vanilla JavaScript XMLHttpRequest everything works fine but with PrototypeJS it won't work because it seams Prototype sets some custom headers and I don't know how to prevent it.

    I tried it in Prototype via:

    new Ajax.Request('some.foreign-host.com/res.php', {
      method: 'post',
      postBody: 'foo=bar', 
      contentType: 'application/x-www-form-urlencoded', 
      onSuccess: function(e){
        // some custom code
      }
    });
    

    Any idea how to get Prototype to send such a simple CORS Request?


    I have a dump of the Headers created by a plain JavaScript XMLHttpRequest:

    POST /bthesis/returnJSON.php HTTP/1.1    
    Host: foreign-host.com                         
    Connection: keep-alive                   
    Referer: this-host.com
    Content-Length: 9                        
    Origin: this-host.com     
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Accept: */*                              
    User-Agent: [...]
    Accept-Encoding: gzip,deflate,sdch       
    Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
    

    and the Headers created by a Prototype Request:

    OPTIONS /bthesis/returnJSON.php HTTP/1.1 
    Host: foreign-host.com                        
    Connection: keep-alive                   
    Referer: this-host.com
    Access-Control-Request-Method: POST      
    Origin: this-host.com      
    Access-Control-Request-Headers: X-Prototype-Version, X-Requested-With, Content-type, Accept
    Accept: */*                              
    User-Agent: [...]
    Accept-Encoding: gzip,deflate,sdch       
    Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
    

    Prototype uses a totally different header set... which leads to following error in the console:

    XMLHttpRequest cannot load foreign-host.com/bthesis/returnJSON.php. Request header field X-Prototype-Version is not allowed by Access-Control-Allow-Headers. Refused to get unsafe header "X-JSON"

    The strange thing is, that the Webserver returns in both cases the requested resource (I see it in the 'Resources' View of the developer console in chrome) but it seams that prototype has no access to it somehow