Same browser (Safari.latest) on the same computer, the Prototype method gives me a security failure (Origin [my host] is not allowed by Access-Control-Allow-Origin.) while the long-hand XHR (inside a Prototype observer) just works without any comment:
Prototype: $('zip').observe('change',function(evt){ var elm = this; new Ajax.Request('http://zip.elevenbasetwo.com', { method: 'get', parameters: {zip: $F(elm)}, onComplete: function(transport){ var data = responseText.evalJSON(); $('city').setValue(data.city); $('state').setValue(data.state); } }); });
XHR: $('zip').observe('change',function(evt){ var client = new XMLHttpRequest(); client.open("GET", "http://zip.elevenbasetwo.com?zip=" + $F(this), true); client.onreadystatechange = function() { if(client.readyState == 4) { var data = client.responseText.evalJSON(); $('city').setValue(data.city); $('state').setValue(data.state); }; }; client.send(); });
I don't trust this to work in the range of browsers supported by Prototype, naturally, so I'd really like to know what I could do to get it to work in Prototype.
* - url (String): The URL to fetch. When the _same-origin_ policy is
in
* effect (as it is in most cases), `url` **must** be a relative URL or
an
* absolute URL that starts with a slash (i.e., it must not begin with
* `http`).
On Apr 10, 7:52 pm, Walter Lee Davis <wa...@wdstudio.com> wrote:
I understand the SOP, I was wondering why it worked when I violated SOP from a hard-coded XHR request. Under the hood, it is my understanding that Prototype sets up a very similar XHR request anyway. It doesn't make any sense that the one would work while the other did not. This server is specifically kinked to allow a request such as this, or else the SOP would cause it to fail no matter what. Can anyone point out the flaw in my logic here?
> * - url (String): The URL to fetch. When the _same-origin_ policy is > in > * effect (as it is in most cases), `url` **must** be a relative URL or > an > * absolute URL that starts with a slash (i.e., it must not begin with > * `http`).
> On Apr 10, 7:52 pm, Walter Lee Davis <wa...@wdstudio.com> wrote: >> Typo, fixed; still fails, same error, before ever reaching this line.
>> On Apr 10, 2012, at 10:50 PM, Walter Lee Davis wrote:
>>> var data = responseText.evalJSON();
>> s/b var data = transport.responseText.evalJSON();
>> Walter
> -- > You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group. > To post to this group, send email to prototype-scriptaculous@googlegroups.com. > To unsubscribe from this group, send email to prototype-scriptaculous+unsubscribe@googlegroups.com. > For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en.
> Same browser (Safari.latest) on the same computer, the Prototype method > gives me a security failure (Origin [my host] is not allowed by > Access-Control-Allow-Origin.) while the long-hand XHR (inside a Prototype > observer) just works without any comment:
> Two differences I can notice:
1. Prototype sets request headers 'X-Requested-With', 'X-Prototype-Version', 'Accept' with setRequestHeaders() - you don't 2. Prototype calls send with null argument this.transport.send(null); // Prototype vs client.send(); // your raw XHR
If you can test your code with these two changes - will it raise error?
> Same browser (Safari.latest) on the same computer, the Prototype method gives me a security failure (Origin [my host] is not allowed by Access-Control-Allow-Origin.) while the long-hand XHR (inside a Prototype observer) just works without any comment:
> Two differences I can notice: > 1. Prototype sets request headers 'X-Requested-With', 'X-Prototype-Version', 'Accept' with setRequestHeaders() - you don't > 2. Prototype calls send with null argument > this.transport.send(null); // Prototype > vs > client.send(); // your raw XHR
> If you can test your code with these two changes - will it raise error?
Thanks very much for the suggestion. It looks as though ANY setRequestHeader invocation at all is enough to scuttle the request. I tried commenting one, then two, then all of them out. Without those three lines, the request works fine -- even with the null in the send. But add any one of them back, and the request fails. It seems to be an issue on their server (BaseHTTP/0.3 Python/2.7.1+ according to FireBug). I'll file a bug and see what happens.
Request URL: http://zip.elevenbasetwo.com/?zip=a Request Method: OPTIONS Status Code: 501 Not Implemented *Request Headers* Accept: */* Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.3 Accept-Encoding: gzip,deflate,sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Access-Control-Request-Headers: x-xxx, origin Access-Control-Request-Method: GET Connection: keep-alive Host: zip.elevenbasetwo.com Origin: https://groups.google.com User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.142 Safari/535.19 *Response Headers* Connection: close Content-Type: text/html Date: Fri, 13 Apr 2012 09:20:32 GMT Server: BaseHTTP/0.3 Python/2.7.1+
It seems that some browsers (like Firefox and WebKit-based) may send CORS requests without preflight for text/plain resources when no additional headers are set. In other cases they send preflighted 'OPTIONS' request, which is not implemented in this 'BaseHTTP/0.3 Python/2.7.1+' server.
Thanks very much for the added detail. I filed an issue on the Github project for the Python server, and within hours another Githubber had posted a pull request fixing the bug. The server was just not aware of what to do if it got such an OPTIONS request, so it was falling over.
> It seems that some browsers (like Firefox and WebKit-based) may send CORS requests without preflight for text/plain resources when no additional headers are set. In other cases they send preflighted 'OPTIONS' request, which is not implemented in this 'BaseHTTP/0.3 Python/2.7.1+' server.