Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ If instead you want to allow everything to be cached, except your "/api/users" a
httpRequestInterceptorCacheBusterProvider.setMatchlist([/.*orders.*/,/.*users.*/],true);
});

If you need custom logic instead of regular expression matching, you can supply a match function instead of a matchlist. The second boolean argument "blacklist" operates the same. The match function is called with a single url argument. Return a truthy value if the url matches:

angular.module('yourApp', ['ngCacheBuster'])
.config(function(httpRequestInterceptorCacheBusterProvider){
httpRequestInterceptorCacheBusterProvider.setMatchFunction(function(url) {
return url.length % 2;
},true);
});

# use

That's it! All your resource calls will have a cache buster added for anything not in the whitelist, or if you specified "blacklist", for everything matching the blacklist,
Expand Down
121 changes: 65 additions & 56 deletions angular-cache-buster.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,70 @@ angular.module('ngCacheBuster', [])
.config(['$httpProvider', function($httpProvider) {
return $httpProvider.interceptors.push('httpRequestInterceptorCacheBuster');
}])
.provider('httpRequestInterceptorCacheBuster', function() {

this.matchlist = [/.*partials.*/, /.*views.*/ ];
this.logRequests = false;

//Default to whitelist (i.e. block all except matches)
this.black=false;

//Select blacklist or whitelist, default to whitelist
this.setMatchlist = function(list,black) {
this.black = typeof black != 'undefined' ? black : false
this.matchlist = list;
};


this.setLogRequests = function(logRequests) {
this.logRequests = logRequests;
};

this.$get = ['$q', '$log', function($q, $log) {
var matchlist = this.matchlist;
var logRequests = this.logRequests;
var black = this.black;
if (logRequests) {
$log.log("Blacklist? ",black);
}
return {
'request': function(config) {
//Blacklist by default, match with whitelist
var busted= !black;

for(var i=0; i< matchlist.length; i++){
if(config.url.match(matchlist[i])) {
busted=black; break;
}
}

//Bust if the URL was on blacklist or not on whitelist
if (busted) {
var d = new Date();
config.url = config.url.replace(/[?|&]cacheBuster=\d+/,'');
//Some url's allready have '?' attached
config.url+=config.url.indexOf('?') === -1 ? '?' : '&'
config.url += 'cacheBuster=' + d.getTime();
}

if (logRequests) {
var log='request.url =' + config.url
busted ? $log.warn(log) : $log.info(log)
}

return config || $q.when(config);
}
}
}];
});
.provider('httpRequestInterceptorCacheBuster', function() {

this.matchlist = [/.*partials.*/, /.*views.*/ ];
this.logRequests = false;

//Default to whitelist (i.e. block all except matches)
this.black=false;

//Select blacklist or whitelist, default to whitelist
this.setMatchlist = function(list, black) {
this.black = typeof black != 'undefined' ? black : false;
this.matchlist = list;
};

this.setMatchFunction = function(matchFn, black) {
this.black = typeof black != 'undefined' ? black : false;
this.matchFn = matchFn;
};

this.setLogRequests = function(logRequests) {
this.logRequests = logRequests;
};

this.$get = ['$q', '$log', function($q, $log) {
var matchlist = this.matchlist;
var matchFn = this.matchFn;
var logRequests = this.logRequests;
var black = this.black;
if (logRequests) {
$log.log("Blacklist? ", black);
}
return {
'request': function(config) {
//Blacklist by default, match with whitelist
var busted = !black;

if (typeof matchFn === 'function') {
if (matchFn(config.url)) {
busted = black;
}
} else {
for(var i = 0; i < matchlist.length; i++){
if (config.url.match(matchlist[i])) {
busted = black; break;
}
}
}

//Bust if the URL was on blacklist or not on whitelist
if (busted) {
var d = new Date();
config.url = config.url.replace(/[?|&]cacheBuster=\d+/, '');
//Some url's allready have '?' attached
config.url += config.url.indexOf('?') === -1 ? '?' : '&'
config.url += 'cacheBuster=' + d.getTime();
}

if (logRequests) {
var log = 'request.url =' + config.url
busted ? $log.warn(log) : $log.info(log)
}

return config || $q.when(config);
}
}
}];
});
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
"ie9"
],
"author": "saintmac <martin.saintmac@gmail.com> (Martin Saint-Macary, http://vyte.in)",
"contributors": ["Alfred Bratterud <alfred.bratterud@hioa.no>"],
"contributors": [
"Alfred Bratterud <alfred.bratterud@hioa.no>",
"Donovan Mikrot <donovan@donovan.mn>"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/saintmac/angular-cache-buster/issues"
Expand All @@ -38,6 +41,7 @@
"requirejs": "~2.1.11",
"karma-requirejs": "~0.2.1",
"karma-phantomjs-launcher": "~0.1.2",
"karma": "~0.12.15"
"karma": "~0.12.15",
"karma-junit-reporter": "~0.3.3"
}
}
93 changes: 88 additions & 5 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('ngCacheBuster', function () {

beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
$http = $injector.get('$http');
$http = $injector.get('$http');
}));

afterEach(function() {
Expand Down Expand Up @@ -62,7 +62,7 @@ describe('ngCacheBuster', function () {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});

//Whitelist, views
describe('with a views request', function() {
it('should add a cache buster', function() {
Expand Down Expand Up @@ -176,7 +176,7 @@ describe('ngCacheBuster', function () {
$httpBackend.flush();
});
});

//Blacklist, other
describe('with any other request', function() {
it('should not add a cache buster', function() {
Expand All @@ -186,7 +186,90 @@ describe('ngCacheBuster', function () {
$httpBackend.flush();
});
});


});

//Match function
describe('configuring the provider with a match function', function() {
beforeEach(function() {
var matchlist = [/.*users.*/, /.*orders.*/];
module('ngCacheBuster');
module(function(httpRequestInterceptorCacheBusterProvider){
httpRequestInterceptorCacheBusterProvider.setMatchFunction(function (url) {
for(var i = 0; i < matchlist.length; i++){
if (url.match(matchlist[i])) {
return true;
}
}
return false;
}, true);
httpRequestInterceptorCacheBusterProvider.setLogRequests(true);
});
});

beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
$http = $injector.get('$http');
}));

afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});

//Match function, users
describe('with an api/users request', function() {
it('should add a cache buster', function() {
var req = '/api/users/654645';
var regex_friendly_req = req.replace(/\//g, '\\/');
var expected = new RegExp(regex_friendly_req + '\\?cacheBuster=[0-9]+')
$httpBackend.expectGET(expected).respond(200);
$http.get(req);
$httpBackend.flush();
});
});

//Match function, api/orders
describe('with an api/orders request', function() {
it('should add a cache buster', function() {
var req = '/api/orders/654645';
var regex_friendly_req = req.replace(/\//g, '\\/');
var expected = new RegExp(regex_friendly_req + '\\?cacheBuster=[0-9]+')
$httpBackend.expectGET(expected).respond(200);
$http.get(req);
$httpBackend.flush();
});
});

//Match function, with existing query params
describe('with an api/orders request with existing query-string parameter', function() {
it('should add a cache buster, but not break existing params', function() {
var req = '/api/orders/654645?orderid=115';
var regex_friendly_req = req.replace(/\//g, '\\/').replace(/\?/g,'\\?')
var expected = new RegExp(regex_friendly_req + '&cacheBuster=[0-9]+')
$httpBackend.expectGET(expected).respond(200);
$http.get(req);
$httpBackend.flush();
});
});

//Match function, partials
describe('with a partials request', function() {
it('should not add a cache buster', function() {
var req = '/bower_components/mymodule/partials/home.html';
$httpBackend.expectGET(req).respond(200);
$http.get(req);
$httpBackend.flush();
});
});

//Match function, other
describe('with any other request', function() {
it('should not add a cache buster', function() {
var req = '/task/1234';
$httpBackend.expectGET(req).respond(200);
$http.get(req);
$httpBackend.flush();
});
});
});
});