4 * Create an object like mw.Api, but automatically handling everything required to communicate
5 * with another MediaWiki wiki via cross-origin requests (CORS).
7 * The foreign wiki must be configured to accept requests from the current wiki. See
8 * <https://www.mediawiki.org/wiki/Manual:$wgCrossSiteAJAXdomains> for details.
10 * var api = new mw.ForeignApi( 'https://commons.wikimedia.org/w/api.php' );
14 * } ).done( function ( data ) {
15 * console.log( data );
18 * To ensure that the user at the foreign wiki is logged in, pass the `assert: 'user'` parameter
19 * to #get/#post (since MW 1.23): if they are not, the API request will fail. (Note that this
20 * doesn't guarantee that it's the same user.)
22 * Authentication-related MediaWiki extensions may extend this class to ensure that the user
23 * authenticated on the current wiki will be automatically authenticated on the foreign one. These
24 * extension modules should be registered using the ResourceLoaderForeignApiModules hook. See
25 * CentralAuth for a practical example. The general pattern to extend and override the name is:
27 * function MyForeignApi() {};
28 * OO.inheritClass( MyForeignApi, mw.ForeignApi );
29 * mw.ForeignApi = MyForeignApi;
31 * @class mw.ForeignApi
36 * @param {string|mw.Uri} url URL pointing to another wiki's `api.php` endpoint.
37 * @param {Object} [options] See mw.Api.
39 * @author Bartosz DziewoĆski
42 function CoreForeignApi( url, options ) {
43 if ( !url || $.isPlainObject( url ) ) {
44 throw new Error( 'mw.ForeignApi() requires a `url` parameter' );
47 this.apiUrl = String( url );
49 options = $.extend( /*deep=*/ true,
58 // Add 'origin' query parameter to all requests.
59 origin: this.getOrigin()
65 // Call parent constructor
66 CoreForeignApi.parent.call( this, options );
69 OO.inheritClass( CoreForeignApi, mw.Api );
72 * Return the origin to use for API requests, in the required format (protocol, host and port, if
78 CoreForeignApi.prototype.getOrigin = function () {
79 var origin = location.protocol + '//' + location.hostname;
80 if ( location.port ) {
81 origin += ':' + location.port;
89 CoreForeignApi.prototype.ajax = function ( parameters, ajaxOptions ) {
90 var url, origin, newAjaxOptions;
92 // 'origin' query parameter must be part of the request URI, and not just POST request body
93 if ( ajaxOptions.type === 'POST' ) {
94 url = ( ajaxOptions && ajaxOptions.url ) || this.defaults.ajax.url;
95 origin = ( parameters && parameters.origin ) || this.defaults.parameters.origin;
96 url += ( url.indexOf( '?' ) !== -1 ? '&' : '?' ) +
97 'origin=' + encodeURIComponent( origin );
98 newAjaxOptions = $.extend( {}, ajaxOptions, { url: url } );
100 newAjaxOptions = ajaxOptions;
103 return CoreForeignApi.parent.prototype.ajax.call( this, parameters, newAjaxOptions );
107 mw.ForeignApi = CoreForeignApi;
109 }( mediaWiki, jQuery ) );