15. Today’s Web Applications
“Learning JavaScript used to
mean you weren't a serious
software developer.
Today, not learning Javascript
means the same thing.” -
Jens Ohlig
18. Same Origin Policy
• Important security concept within modern browsers
• Originally released with Netscape Navigator 2 (March 1996)
• Permits script tags, images, css from any site (origin)
• Permits XHR only from the same site (origin)
• Prevents access to most methods and properties across different sites
(origins)
22. JSONP
• Stands for JSON with Padding
• Script tags are exception to the Same Origin Policy
• Just loading a script with JSON data cannot help us (will be lost in the
global context)
• The padding allows us to wrap the result with a global callback
• The response will be evaluated by the JavaScript interpreter and invoked
24. Why not use JSONP?
• Only valid for GET requests
• Limited payload size
• Not flexible (no headers etc.)
• Insecure
• Causes IE to leak memory (most implementations)
26. CORS
• Stands for Cross Origin Resource Sharing
• A W3C spec that allows cross-domain communication from the browser
• Defines a way to determine whether or not to allow the cross-origin
request
• Works by adding new HTTP headers
28. Why not use CORS?
• Only IE9+ support it natively (IE8 only via XDomainRequest)
• Requires “preflights” for requests other than GET or POST (with certain
MIME types) and for JSON.
31. lpAjax to the rescue
• Developed in LivePerson
• Self contained (Vanilla JS)
• Easy to use
• Used by entire LivePerson clients as a transport layer
• Supports three main transport types: XHR, JSONP
AND
postMessage
32. Browser to server communications
url.com
api.liveperson.com
api.liveperson.com/pm.html
lpAjax postmessage client
pm.html
Postmessage server
xhr
33. lpAjax postMessage
• It works!!!
• Almost as fast as JSONP
• Can work with REST API’S
• Very small latency for first API call (iframe creation)
• Small latency for serialization of data for use with postMessage
• Beware: 401 Response Codes & failed requests issues
37. Backbone with lpAjax postMessage
• Backbone utilizes jQuery as a transport
• jQuery allows us to manipulate ajax transports at multiple levels
• $.ajaxPrefilters - Handle custom options/modify existing options before
request is processed by $.ajax()
• $.ajaxTransport - Creates an object that handles the actual transmission
of Ajax data and used by $.ajax() to issue requests
• Converters – to manipulate and parse the data returned from the
response
38. Our custom ajaxPrefilter
// Register jQuery Ajax Prefilter that detects cross-domain requests and set the request data-type to "postmessage".
$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
// Get our current origin
var originBrowser = window.location;
// Get the API url origin
var originApi = document.createElement("a");
originApi.href = options.url;
// Skip Same Origin API URL's
if (originApi.hostname == originBrowser.hostname &&
originApi.port == originBrowser.port &&
originApi.protocol == originBrowser.protocol) {
return;
}
// If the domains aren't the same and this isn't a jsonp request, force the data-type of the request to "postmessage".
if ("jsonp" !== options.dataType.toLowerCase()) {
// Redirect to our “postmessage” temporary transport type
return "postmessage";
}
});
39. Our ajaxTransport Implementation
// Create the postmessage transport handler (which will proxy the request to lpAjax) and register it for handling postmessage
// (the '+' forces overriding any existing implementations for a transport).
$.ajaxTransport("+postmessage", function (options, originalOptions, jqXHR) {
// Remove the temporary transport dataType
options.dataTypes.shift();
return {
send:function (requestHeaders, done) {
// Build the request object based on what jQuery created for us so far
var req = $.extend({}, lpTag.taglets.lpAjax_request);
req.headers = requestHeaders;
req.method = originalOptions.type;
req.data = originalOptions.data;
req.url = options.url;
// Implement the success and error handlers
req.success = function (data) {
handlePostMessageResponse(data, done);
};
req.error = function (data) {
handlePostMessageResponse(data, done);
};
// Issue the request using lpAjax postMessage.
lpAjax.postmessage.issueCall(req);
},
abort:function () {}
};
}));
40. Implement the response handler
// Create the response handler for lpAjax to call
var handlePostMessageResponse = function (data, done) {
// Do any parsing on the response if needed - Here I do nothing for simplicity
// Now call the jQuery callback to return the response to jQuery handling
done(
data.code, // status,
data.status, // nativeStatusText,
data.body, // responses,
data.headers // headers
);
};
41. Backbone with lpAjax postMessage
“If you can’t explain it simply,
you don’t understand it well
enough.” -Leonardo Da Vinci
Creates each domain iframe only onceThere are browsers which already support postMessage with objects (with no need for serialization)401 response code will cause the browser to pop up an authentication (can be fixed by overriding the default WWW-Authenticate: Basic realm=“xxx”header) 8 consecutive failed requests from the same iframe will abort the iframe usage
Creates each domain iframe only onceThere are browsers which already support postMessage with objects (with no need for serialization)401 response code will cause the browser to pop up an authentication (can be fixed by overriding the default WWW-Authenticate: Basic realm=“xxx”header) 8 consecutive failed requests from the same iframe will abort the iframe usage
Creates each domain iframe only onceThere are browsers which already support postMessage with objects (with no need for serialization)401 response code will cause the browser to pop up an authentication (can be fixed by overriding the default WWW-Authenticate: Basic realm=“xxx”header) 8 consecutive failed requests from the same iframe will abort the iframe usage
Creates each domain iframe only onceThere are browsers which already support postMessage with objects (with no need for serialization)401 response code will cause the browser to pop up an authentication (can be fixed by overriding the default WWW-Authenticate: Basic realm=“xxx”header) 8 consecutive failed requests from the same iframe will abort the iframe usage
Creates each domain iframe only onceThere are browsers which already support postMessage with objects (with no need for serialization)401 response code will cause the browser to pop up an authentication (can be fixed by overriding the default WWW-Authenticate: Basic realm=“xxx”header) 8 consecutive failed requests from the same iframe will abort the iframe usage