-
27 Mar 2012 12:51 PM #1
Cross Origin issue / is Sencha doing something special for CORS?
Cross Origin issue / is Sencha doing something special for CORS?
I'm having an issue with Cross Origin Resource Sharing (CORS).
I've set up my server to handle CROS request successfuly.
To verify this was working I used a simple test like:
Btw: yy origin was a different port on localhost.Code:<script> var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://localhost:8888/products', true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { console.log('responseText: ' + xhr.responseText); } }; xhr.send(); </script>
This works nice as my server is adding the necessary Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Max-Age headers.
When leaving this out, above example fails (as expected) because the famous Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
The only thing it proves my CORS seems to be set up correctly from server perspective, and I can make actual requests from the client.
Now back to using Sencha. In my case I'm using a Rest proxy.
My store autoloads but this fails with Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
I've debugged the server and I found out the (Sencha) application is first making an OPTIONS call.
My server sends back the CORS headers and everything seems to be fine, except that in the (Sencha) application is giving a: Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
I wonder if Sencha sending the OPTIONS method and what criteria is used to determine if the origin is allowed or not.
Note that the simple xhr example above is not sending a OPTIONS call.
Hope somebody can shed a light on this, as I'm stuck..
-
27 Mar 2012 1:13 PM #2
use jsonp instead of ajax calls
trainings / workshops / consulting: Sencha Touch / Ext JS
Profile on SenchaDevs
www: http://www.nils-dehl.de
twitter: nilsdehl
meetup: Sencha Touch / Ext JS Meetup Frankfurt
videos: http://vimeo.com/album/1621422
conference photos: http://www.flickr.com/photos/nils-dehl/
-
27 Mar 2012 3:12 PM #3
I have used CORS successfully with a few Sencha Touch applications. I didn't have to change anything on the Sencha side. I've included an example of the server-side setup that I've used. It utilizes the Tornado webserver in Python. Hopefully it'll be of some use to you.
Code:import tornado.web class BaseHandler(tornado.web.RequestHandler): def set_default_headers(self): self.add_header('Access-Control-Allow-Origin', self.request.headers.get('Origin', '*')) # You could also add 'GET' here, or any other HTTP methods self.add_header('Access-Control-Request-Method', 'POST') # This is needed because Sencha sends the 'X-Requested-With' by default self.add_header('Access-Control-Allow-Headers', 'X-Requested-With')
-
27 Mar 2012 10:48 PM #4
@mrsunshine: JsonP is no option as I need full Rest support including POST, PUT and DELETE. JsonP only supports GET.
@wnielson Thanks for that, but I'm having a very similar setup.
Let me add more details what I'm observing.
When ST tries to autoload a store via a Rest proxy it makes an OPTIONS request like:
Note that I'm using the Jetty CrossOriginFilter which also outputs the following debug info:Code:08:32:29,505 DEBUG [myapp.RequestLoggerFilter] Request Logger: OPTIONS http://localhost:8888/products?_dc=1332916349491&secretKey=blabla&page=1&start=0&limit=25 Header: Host = localhost:8888 Header: Connection = keep-alive Header: Access-Control-Request-Method = GET Header: Origin = http://localhost:8080 Header: User-Agent = Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11 Header: Access-Control-Request-Headers = Origin, X-Requested-With Header: Accept = */* Header: Referer = http://localhost:8080/ Header: Accept-Encoding = gzip,deflate,sdch Header: Accept-Language = en-US,en;q=0.8 Header: Accept-Charset = ISO-8859-1,utf-8;q=0.7,*;q=0.3 Parameter: limit = 25 Parameter: secretKey = blabla Parameter: start = 0 Parameter: page = 1 Parameter: _dc = 1332916349491
which indicates everything is fine with the preflight request.Code:08:32:29,521 DEBUG [org.eclipse.jetty.servlets.CrossOriginFilter] Cross-origin request to /products is a preflight cross-origin request 08:32:29,521 DEBUG [org.eclipse.jetty.servlets.CrossOriginFilter] Access-Control-Request-Method is GET 08:32:29,521 DEBUG [org.eclipse.jetty.servlets.CrossOriginFilter] Method GET is among allowed methods [GET, HEAD, POST, PUT, DELETE] 08:32:29,521 DEBUG [org.eclipse.jetty.servlets.CrossOriginFilter] Access-Control-Request-Headers is Origin, X-Requested-With 08:32:29,521 DEBUG [org.eclipse.jetty.servlets.CrossOriginFilter] Headers [Origin, X-Requested-With] are among allowed headers [X-Requested-With, Content-Type, Accept, Origin]
And then the following response headers are sent back:
So far so good I would say.Code:Access-Control-Allow-Origin: http://localhost:8080 Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1800 Access-Control-Allow-Methods: GET,HEAD,POST,PUT,DELETE Access-Control-Allow-Headers: X-Requested-With,Content-Type,Accept,Origin
After this request I don't see the real GET request coming in. Instead my console is displaying:
XMLHttpRequest cannot load http://localhost:8888/products?_dc=1...art=0&limit=25. Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.
So it seems based on the above response for the OPTIONS request the (ST) application is thinking it's not allowed to make the request.
I wonder if this is related to ST or my browser. I'm using Chrome 17.0.963.83 m. I believe Chrome fully support CORS.
Any further help appreciated.
-
27 Mar 2012 11:38 PM #5
OK I got a little bit further now.
While changing my test.htlm to:
I set a request header explicitly. This will cause the xhr to send a preflight request (OPTIONS).Code:var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://localhost:8888/products?secretKey=reflection', true); xhr.setRequestHeader('Access-Control-Request-Headers', 'Origin, X-Requested-With'); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { console.log('responseText: ' + xhr.responseText); } }; xhr.send();
With above code Google Chrome gives me:
Refused to set unsafe header "Access-Control-Request-Headers"
In matter of fact in this case the OPTIONS request is not executed (as the header was not set) and it continues with the 'real' GET request which works (again).
This also means ST is in some way able to set those 'unsafe' headers in the xhr used internally, or maybe implemented this differently?
-
28 Mar 2012 6:36 AM #6
Note that I implemented CORS using this link: http://www.sencha.com/forum/showthre...aring-requests
Would be nice if ST would provide CORS aware proxies in the future.


Reply With Quote