Disable JSONP cache breaking in jQuery

Change-Id: Ie3b80b0c2f8ce734c6d08418c7b19a7e24c2d5eb
Mingle: https://wikimedia.mingle.thoughtworks.com/projects/multimedia/cards/547
This commit is contained in:
Gergő Tisza 2014-04-29 22:06:26 +00:00
parent 5980cd7322
commit 7a4a8e90ad
2 changed files with 42 additions and 0 deletions

View file

@ -68,6 +68,8 @@
if ( repoInfo.apiUrl ) {
ajaxOptions.url = repoInfo.apiUrl;
ajaxOptions.dataType = 'jsonp';
ajaxOptions.cache = true; // do not append `_=<timestamp>` to the URL
ajaxOptions.jsonpCallback = this.getCallbackName( username );
cacheKey = cacheKey + '|' + repoInfo.apiUrl; // local and remote user names could conflict
}
@ -90,5 +92,23 @@
} );
};
/**,
* Generate JSONP callback function name.
* jQuery uses a random string by default, which would break caching.
* On the other hand the callback needs to be unique to avoid surprises when multiple
* requests run in parallel. And of course needs to be a valid JS variable name.
* @param username
*/
UserInfo.prototype.getCallbackName = function ( username ) {
// Javascript variable name charset rules are fairly lax but better safe then sorry,
// so let's encode every non-alphanumeric character.
// Per http://stackoverflow.com/questions/1809153/maximum-length-of-variable-name-in-javascript
// length should not be an issue (might add a few hundred bytes to the request & response size
// for very long usernames, but we can live with that).
return 'mmv_userinfo_' + mw.util.rawurlencode( username )// encodes all characters except -.~_
.replace( /-/g, '%2D' ).replace( /\./g, '%2E' ).replace( /~/g, '%7E' ).replace( /_/g, '%5F' )
.replace( /%/g, '_' );
};
mw.mmv.provider.UserInfo = UserInfo;
}( mediaWiki, jQuery, OO ) );

View file

@ -163,4 +163,26 @@
QUnit.start();
} );
} );
QUnit.test( 'getCallbackName()', 6, function ( assert ) {
var userInfoProvider = new mw.mmv.provider.UserInfo( {} );
function assertValidVariableName( username ) {
/*jshint evil:true */
var varName = userInfoProvider.getCallbackName( username );
try {
eval( 'var ' + varName + ';');
assert.ok( true, 'Variable name ' + varName + ' generated from ' + username + ' is valid' );
} catch ( e ) {
assert.ok( false, 'Variable name ' + varName + ' generated from ' + username + ' is invalid' );
}
}
assertValidVariableName( 'simple' );
assertValidVariableName( 'Help! I have spaces!' );
assertValidVariableName( 'oh_noes_i_has_underline' );
assertValidVariableName( '$\'"+!%/=()[]{}:;<>,.?|' );
assertValidVariableName( 'イチカワ エツヤ' );
assertValidVariableName( new Array( 256 ).join( 'イ' ) ); // longest possible name, 255*2 bytes
} );
}( mediaWiki, jQuery ) );