Saturday, May 30, 2015

SPA-CORS-Concept


Objective: Objective of this document is to demonstrate how browser behaves when making a cross origin resource request.

Step 1: Go to the UI project. DynamicDataUI
Step 2: Start it


Step 3: Start the data service


Step 4:
Ensure the back end service(NodeJsPostgresDynamicData) is working. Note the url. Basically the page resides in the same module as the back end service so there is no cross site request made.
You will get lot of popups click ok on all.


Step 5:
Ensure sorting by client works.
[TODO-Confirm]When fewer than 10 rows no call is made to the server. Watch it in the console.


Step 6: Now try the CORS on firefox.
Error: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3000/api/v1/invoicesMetaData?_search=false&nd=1432587205781&rows=10&page=1&sidx=c2&sord=desc. (Reason: CORS header 'Access-Control-Allow-Origin' missing).




Error from UI Server console.

maheshs-mbp-2:DynamicDataUI maheshrajannan$ node bin/www
::1 - - [25/May/2015:20:53:24 +0000] "GET /DynamicHeaderProperties HTTP/1.1" 200 12244 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:38.0) Gecko/20100101 Firefox/38.0"
::1 - - [25/May/2015:20:59:22 +0000] "GET /DynamicHeaderProperties HTTP/1.1" 200 12244 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.6.3 (KHTML, like Gecko) Version/7.1.6 Safari/537.85.15"
::1 - - [25/May/2015:20:59:23 +0000] "GET /favicon.ico HTTP/1.1" 500 1637 "http://localhost:8080/DynamicHeaderProperties" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.6.3 (KHTML, like Gecko) Version/7.1.6 Safari/537.85.15"
Error: Failed to lookup view "error" in views directory "/Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/views"
at EventEmitter.app.render (/Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/node_modules/express/lib/application.js:519:17)
at ServerResponse.res.render (/Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/node_modules/express/lib/response.js:933:7)
at /Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/app.js:51:9
at Layer.handle_error (/Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/node_modules/express/lib/router/layer.js:58:5)
at trim_prefix (/Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/node_modules/express/lib/router/index.js:300:13)
at /Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/node_modules/express/lib/router/index.js:270:7
at Function.proto.process_params (/Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/node_modules/express/lib/router/index.js:321:12)
at IncomingMessage.next (/Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/node_modules/express/lib/router/index.js:261:10)
at fn (/Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/node_modules/express/lib/response.js:928:25)
at EventEmitter.app.render (/Users/maheshrajannan/Samples/Workspaces/nodeJs/Project/DynamicDataUI/node_modules/express/lib/application.js:521:14)


Step 7:

Try the same in safari.

Step 8:

Now the fix on the UI side (DynamicHeaderProperties.html)






Step 9:

Now the fix on the server side. Basically to allow it to send jsonp requests.
Just one character change.
Res.json( to → res.jsonp(


Short Notes:

This simply means we are bypassing the security provided by the browser. It is therefore not recommended(Ref:2). What it tells the browser is this is a script and instead of executing the script, it loads the json data. The final conclusion from the article is as follows

These days, CORS is the recommeded approach vs. JSONRequest. JSONP is still useful for older browser support, but given the security implications, unless you have no choice CORS is the better choice.

Quotes from the article

The one item that bypasses this limitation is <script> tags. When you use a script tag, the domain limitation is ignored, but under normal circumstances, you can't really DO anything with the results, the script just gets evaluated.
Enter JSONP. When you make your request to a server that is JSONP enabled, you pass a special parameter that tells the server a little bit about your page. That way, the server is able to nicely wrap up its response in a way that your page can handle.
It's also worth noting the one major issue with JSONP: you lose a lot of control of the request. For example, there is no "nice" way to get proper failure codes back.“

Step 10:

Doing it the right way. Using fine grained CORS support, so that server can control if the request can be served or not, on the basis of specific domain.



I am working on to clean up my code and I will publish the code, after that. This is written using node js and grid is written using jqgrid.

References:

  1. The End