I'm trying to create a very basic client-side router using page.js. The idea being that when you visit a route, if you try and use a render
method, then the render
method will find the view you pass to it (by retrieving it from the server if necessary), then interpolate the view using lodash templates and finally display it to the user. However, I'm experiencing a weird phenomenon. Despite the fact the below example works absolutely perfectly, I am seeing this in my Chrome network log:
(The image above is quite small. Here is the link: https://i.stack.imgur.com/qyhP6.png)
Now, I am firing off a request to /templates/index.html
and I can verify that both of these requests are representing a XHR to the exact same location (that is, they both are pointing at /templates/index.html
). Here is my router code (yes, I appreciate it needs refactoring):
var page = require('page')
, home = require('./home')
, lodashTemplates = require('lodash.template');
module.exports = function() {
// refactor
var routeContainer = document.querySelector('[data-container]');
// TODO: Refactor this to somewhere else
var render = (function() {
var viewCache = new Map();
return function render(viewName, locals, done) {
if(viewCache.get(viewName) === undefined) {
// cache miss - try and get the template
var request = new XMLHttpRequest();
request.open('GET', '/templates/' + encodeURIComponent(viewName) + '.html');
request.onreadystatechange = function() {
if(request.readyState === 4) {
switch(request.status) {
case 200:
viewCache.set(viewName, lodashTemplates(request.response));
// once we have cached the view, invoke ourselves..
// this could probably be coded better
render(viewName, locals, done);
return;
case 404:
case 500:
throw new Error('unable to retrieve view from server: '+viewName);
}
}
};
request.send();
return;
}
// Do this elsewhere..
var view = viewCache.get(viewName);
var interpolated = view(locals);
routeContainer.innerHTML = interpolated;
};
}());
var thisContext = {
render: render
};
// bind home.index to thisContext which gives it access to the render method
// this should ideally be abstracted away but it will do for proof-of-concept
page('/', home.index.bind(thisContext));
// Always leave this line at the bottom, it is required to activate the routes.
page({ hashbang: true });
};
home.index - this is bound to the thisContext
in the above sample
function index(context, next) {
this.render('index', { foo: 'bar' });
}
This utilizes Browserify for the require
, lodash.template
(npm) and page
(npm) to achieve it's goal. As mentioned before, the result is being displayed correctly, which is why I am confused as to why this error is being shown. Interestingly, this issue only pops up in Chrome - it does not occur however during private browsing on Chrome nor does it occur in Chrome Canary.