Using custom headers with Backbone.sync
Using a similar technique to that discussed in Add a root URL to all Backbone API request it is very easy to add a custom header to Backbone.sync
requests without having to repeat it in every fetch
/save
.
For example, the API of a project I was working on recently needed an Authorization
header, containing the OAuth access token, sent with every sync request. It would have been reasonably trivial to rewrite a Backbone.sync
replacement that handled this, but why write extra code when Backbone.sync
works so well?
/*
* Using AMD/RequireJS
*
* The `auth` module handles OAuth and stores the
* access token that needs to be sent in a header
*/
define(['api/auth'], function (auth) {
'use strict';
/*
* Store a version of Backbone.sync to call from the
* modified version we create
*/
var backboneSync = Backbone.sync;
Backbone.sync = function (method, model, options) {
/*
* The jQuery `ajax` method includes a 'headers' option
* which lets you set any headers you like
*/
options.headers = {
/*
* Set the 'Authorization' header and get the access
* token from the `auth` module
*/
'Authorization': 'Bearer ' + auth.getAccessToken()
};
/*
* Call the stored original Backbone.sync method with
* extra headers argument added
*/
backboneSync(method, model, options);
};
});
Written by Mark Wales
Related protips
7 Responses
Thanks. This is great. Quick question: How does the collection fetch / save know to use this overloaded function rather than the original?
(And do you have the auth.js? Ta).
Thanks.
The example above is assuming that you're using the non-AMD version of Backbone, so Backbone.sync
is in the global scope. When you assign the new function to Backbone.sync
it will therefore over-write the original - just like reassigning any variable.
If you were using the AMD version of Backbone it would be a little trickier. You'd need to setup a file where you import in the AMD Backbone object, then override the Backbone.sync
method, and then return the new version. From then on you'd use that newly created file as your Backbone definition (so you'd only require the original Backbone file once at the top of that file).
The auth.js
module is just a short file that I wrote - it's quite specific to the project.
Thanks for the reply. Really appreciate it.
I am using Require with Backbone, so am a little unsure of where the new sync code should sit to overload the original. (Certainly where I've put it, it doesn't seem to work! ;) )
Cheers,
Ben
So you'd need to setup an empty file in your project called backbone.js
and then put the Backbone.sync
code in it. The only difference is that at the top you'd need to require the original Backbone file (e.g. ../vendor/backbone/backbone.min.js
) with a Backbone
argument name. Then put return Backbone;
at the end. Anywhere else in your project where you need Backbone require your new backbone.js
file (or, even better, set that up to be backbone
in your RequireJS config).
Aha. Yes. Now you've put it like that, it's obvious - overide the whole file.
Thanks again for the help.
nice one, not exactly what I was looking for but pretty damn close and its nice to know that backbones pretty flexible when it comes to this sort of thing.