I'm soliciting feedback regarding the pros/cons of using the
XMLDocument provided by the XMLHttpRequest object.
The motivation for this is an SEO optimization POC I am working on.
Semantic XML content is transformed by the browser via the linked XSL
stylesheet, producing the standard JS,CSS, HTML (and bootstrap JSON
data) found in a typical AngularJS app.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="simple.xsl"?>
<page>
.
.
.
</page>
Subsequent navigations use XHR to retrieve the xml documents
associated with each navigation rather than performing an actual
navigation.
The app is configured with an interceptor that will convert the
semantic XML (consumed by Search Engines) into JSON.
myServices.config(function($httpProvider) {
function exampleInterceptor($q,$log) {
function success(response) {
//If we have xml transform to appropriate json using xslt
if (angular.isObject(response.xml)){
//Reparse xml responseText or use native responseXML?
$
log.info('XML response: ' + response.xml);
}
return response;
}
function error(response) {
var status = response.status;
$log.error('Response status: ' + status + '. ' +
response.responseXML);
return $q.reject(response); //similar to throw response;
}
return function(promise) {
return promise.then(success, error);
}
}
$httpProvider.responseInterceptors.push(exampleInterceptor);
});
What issues would adding the responseXML to the $http params cause
(see below)?
/**
* Callback registered to $httpBackend():
* - caches the response if desired
* - resolves the raw $http promise
* - calls $apply
*/
function done(status, response, headersString, responseXML) {
if (cache) {
if (isSuccess(status)) {
cache.put(config.url, [status, response,
parseHeaders(headersString), responseXML]);
} else {
// remove promise from the cache
cache.remove(config.url);
}
}
resolvePromise(response, status, headersString, responseXML);
$rootScope.$apply();
}
/**
* Resolves the raw $http promise.
*/
function resolvePromise(response, status, headers, responseXML)
{
// normalize internal statuses to 0
status = Math.max(status, 0);
(isSuccess(status) ? deferred.resolve : deferred.reject)({
data: response,
status: status,
headers: headersGetter(headers),
config: config,
xml: responseXML
});
}
// In IE6 and 7, this might be called synchronously when
xhr.send below is called and the
// response is in the cache. the promise api will ensure that to
the app code the api is
// always async
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
completeRequest(
callback, status || xhr.status, xhr.responseText,
xhr.getAllResponseHeaders(), xhr.responseXML);
}
};
xhr.send(post || '');
if (timeout > 0) {
$browserDefer(function() {
status = -1;
xhr.abort();
}, timeout);
}
}
function completeRequest(callback, status, response,
headersString, responseXML) {
// URL_MATCH is defined in src/service/location.js
var protocol = (url.match(URL_MATCH) || ['', locationProtocol])
[1];
// fix status code for file protocol (it's always 0)
status = (protocol == 'file') ? (response ? 200 : 404) : status;
// normalize IE bug (
http://bugs.jquery.com/ticket/1450)
status = status == 1223 ? 204 : status;
callback(status, response, headersString,responseXML);
$browser.$$completeOutstandingRequest(noop);
}
};
}