mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-22 05:06:09 +03:00
Merge pull request #553 from openseadragon/ajax
Allowing XHRs withCredentials for authenticated requests
This commit is contained in:
commit
c55daff222
@ -39,6 +39,7 @@ OPENSEADRAGON CHANGELOG
|
|||||||
* Rect and Point toString() functions are now consistent: rounding values to nearest hundredth
|
* Rect and Point toString() functions are now consistent: rounding values to nearest hundredth
|
||||||
* Overlays appear in the DOM immediately on open or addOverlay (#507)
|
* Overlays appear in the DOM immediately on open or addOverlay (#507)
|
||||||
* imageLoaderLimit now works (#544)
|
* imageLoaderLimit now works (#544)
|
||||||
|
* Added ajaxWithCredentials option (#543)
|
||||||
|
|
||||||
1.2.1: (in progress)
|
1.2.1: (in progress)
|
||||||
|
|
||||||
|
@ -559,8 +559,12 @@
|
|||||||
* If collectionMode is true, specifies the margin, in viewport coordinates, between each TiledImage.
|
* If collectionMode is true, specifies the margin, in viewport coordinates, between each TiledImage.
|
||||||
*
|
*
|
||||||
* @property {String|Boolean} [crossOriginPolicy=false]
|
* @property {String|Boolean} [crossOriginPolicy=false]
|
||||||
* Valid values are 'Anonymous', 'use-credentials', and false. If false, canvas requests will
|
* Valid values are 'Anonymous', 'use-credentials', and false. If false, canvas requests will
|
||||||
* not use CORS, and the canvas will be tainted.
|
* not use CORS, and the canvas will be tainted.
|
||||||
|
*
|
||||||
|
* @property {Boolean} [ajaxWithCredentials=false]
|
||||||
|
* Whether to set the withCredentials XHR flag for AJAX requests (when loading tile sources).
|
||||||
|
* Note that this can be overridden at the {@link OpenSeadragon.TileSource} level.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -919,6 +923,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
tileHost: null,
|
tileHost: null,
|
||||||
initialPage: 0,
|
initialPage: 0,
|
||||||
crossOriginPolicy: false,
|
crossOriginPolicy: false,
|
||||||
|
ajaxWithCredentials: false,
|
||||||
|
|
||||||
//PAN AND ZOOM SETTINGS AND CONSTRAINTS
|
//PAN AND ZOOM SETTINGS AND CONSTRAINTS
|
||||||
panHorizontal: true,
|
panHorizontal: true,
|
||||||
@ -1925,13 +1930,25 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes an AJAX request.
|
* Makes an AJAX request.
|
||||||
* @function
|
* @param {Object} options
|
||||||
* @param {String} url - the url to request
|
* @param {String} options.url - the url to request
|
||||||
* @param {Function} onSuccess - a function to call on a successful response
|
* @param {Function} options.success - a function to call on a successful response
|
||||||
* @param {Function} onError - a function to call on when an error occurs
|
* @param {Function} options.error - a function to call on when an error occurs
|
||||||
|
* @param {Boolean} [options.withCredentials=false] - whether to set the XHR's withCredentials
|
||||||
* @throws {Error}
|
* @throws {Error}
|
||||||
*/
|
*/
|
||||||
makeAjaxRequest: function( url, onSuccess, onError ) {
|
makeAjaxRequest: function( url, onSuccess, onError ) {
|
||||||
|
var withCredentials;
|
||||||
|
|
||||||
|
// Note that our preferred API is that you pass in a single object; the named
|
||||||
|
// arguments are for legacy support.
|
||||||
|
if( $.isPlainObject( url ) ){
|
||||||
|
onSuccess = url.success;
|
||||||
|
onError = url.error;
|
||||||
|
withCredentials = url.withCredentials;
|
||||||
|
url = url.url;
|
||||||
|
}
|
||||||
|
|
||||||
var protocol = $.getUrlProtocol( url );
|
var protocol = $.getUrlProtocol( url );
|
||||||
var request = $.createAjaxRequest( protocol === "file:" );
|
var request = $.createAjaxRequest( protocol === "file:" );
|
||||||
|
|
||||||
@ -1958,6 +1975,10 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (withCredentials) {
|
||||||
|
request.withCredentials = true;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
request.open( "GET", url, true );
|
request.open( "GET", url, true );
|
||||||
request.send( null );
|
request.send( null );
|
||||||
|
@ -38,44 +38,52 @@
|
|||||||
/**
|
/**
|
||||||
* @class TileSource
|
* @class TileSource
|
||||||
* @classdesc The TileSource contains the most basic implementation required to create a
|
* @classdesc The TileSource contains the most basic implementation required to create a
|
||||||
* smooth transition between layer in an image pyramid. It has only a single key
|
* smooth transition between layers in an image pyramid. It has only a single key
|
||||||
* interface that must be implemented to complete it key functionality:
|
* interface that must be implemented to complete its key functionality:
|
||||||
* 'getTileUrl'. It also has several optional interfaces that can be
|
* 'getTileUrl'. It also has several optional interfaces that can be
|
||||||
* implemented if a new TileSource wishes to support configuration via a simple
|
* implemented if a new TileSource wishes to support configuration via a simple
|
||||||
* object or array ('configure') and if the tile source supports or requires
|
* object or array ('configure') and if the tile source supports or requires
|
||||||
* configuration via retreival of a document on the network ala AJAX or JSONP,
|
* configuration via retrieval of a document on the network ala AJAX or JSONP,
|
||||||
* ('getImageInfo').
|
* ('getImageInfo').
|
||||||
* <br/>
|
* <br/>
|
||||||
* By default the image pyramid is split into N layers where the images longest
|
* By default the image pyramid is split into N layers where the image's longest
|
||||||
* side in M (in pixels), where N is the smallest integer which satisfies
|
* side in M (in pixels), where N is the smallest integer which satisfies
|
||||||
* <strong>2^(N+1) >= M</strong>.
|
* <strong>2^(N+1) >= M</strong>.
|
||||||
*
|
*
|
||||||
* @memberof OpenSeadragon
|
* @memberof OpenSeadragon
|
||||||
* @extends OpenSeadragon.EventSource
|
* @extends OpenSeadragon.EventSource
|
||||||
* @param {Number|Object|Array|String} width
|
* @param {Object} options
|
||||||
* If more than a single argument is supplied, the traditional use of
|
* You can either specify a URL, or literally define the TileSource (by specifying
|
||||||
* positional parameters is supplied and width is expected to be the width
|
* width, height, tileSize, tileOverlap, minLevel, and maxLevel). For the former,
|
||||||
* source image at its max resolution in pixels. If a single argument is supplied and
|
* the extending class is expected to implement 'getImageInfo' and 'configure'.
|
||||||
* it is an Object or Array, the construction is assumed to occur through
|
* For the latter, the construction is assumed to occur through
|
||||||
* the extending classes implementation of 'configure'. Finally if only a
|
* the extending classes implementation of 'configure'.
|
||||||
* single argument is supplied and it is a String, the extending class is
|
* @param {String} [options.url]
|
||||||
* expected to implement 'getImageInfo' and 'configure'.
|
* The URL for the data necessary for this TileSource.
|
||||||
* @param {Number} height
|
* @param {Function} [options.success]
|
||||||
|
* A function to be called upon successful creation.
|
||||||
|
* @param {Boolean} [options.ajaxWithCredentials]
|
||||||
|
* If this TileSource needs to make an AJAX call, this specifies whether to set
|
||||||
|
* the XHR's withCredentials (for accessing secure data).
|
||||||
|
* @param {Number} [options.width]
|
||||||
* Width of the source image at max resolution in pixels.
|
* Width of the source image at max resolution in pixels.
|
||||||
* @param {Number} tileSize
|
* @param {Number} [options.height]
|
||||||
|
* Height of the source image at max resolution in pixels.
|
||||||
|
* @param {Number} [options.tileSize]
|
||||||
* The size of the tiles to assumed to make up each pyramid layer in pixels.
|
* The size of the tiles to assumed to make up each pyramid layer in pixels.
|
||||||
* Tile size determines the point at which the image pyramid must be
|
* Tile size determines the point at which the image pyramid must be
|
||||||
* divided into a matrix of smaller images.
|
* divided into a matrix of smaller images.
|
||||||
* @param {Number} tileOverlap
|
* @param {Number} [options.tileOverlap]
|
||||||
* The number of pixels each tile is expected to overlap touching tiles.
|
* The number of pixels each tile is expected to overlap touching tiles.
|
||||||
* @param {Number} minLevel
|
* @param {Number} [options.minLevel]
|
||||||
* The minimum level to attempt to load.
|
* The minimum level to attempt to load.
|
||||||
* @param {Number} maxLevel
|
* @param {Number} [options.maxLevel]
|
||||||
* The maximum level to attempt to load.
|
* The maximum level to attempt to load.
|
||||||
*/
|
*/
|
||||||
$.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLevel ) {
|
$.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLevel ) {
|
||||||
var callback = null,
|
var _this = this;
|
||||||
args = arguments,
|
|
||||||
|
var args = arguments,
|
||||||
options,
|
options,
|
||||||
i;
|
i;
|
||||||
|
|
||||||
@ -102,19 +110,23 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
|||||||
//source
|
//source
|
||||||
$.extend( true, this, options );
|
$.extend( true, this, options );
|
||||||
|
|
||||||
//Any functions that are passed as arguments are bound to the ready callback
|
if (!this.success) {
|
||||||
/*jshint loopfunc:true*/
|
//Any functions that are passed as arguments are bound to the ready callback
|
||||||
for ( i = 0; i < arguments.length; i++ ) {
|
for ( i = 0; i < arguments.length; i++ ) {
|
||||||
if ( $.isFunction( arguments[ i ] ) ) {
|
if ( $.isFunction( arguments[ i ] ) ) {
|
||||||
callback = arguments[ i ];
|
this.success = arguments[ i ];
|
||||||
this.addHandler( 'ready', function ( event ) {
|
//only one callback per constructor
|
||||||
callback( event );
|
break;
|
||||||
} );
|
}
|
||||||
//only one callback per constructor
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.success) {
|
||||||
|
this.addHandler( 'ready', function ( event ) {
|
||||||
|
_this.success( event );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ratio of width to height
|
* Ratio of width to height
|
||||||
* @member {Number} aspectRatio
|
* @member {Number} aspectRatio
|
||||||
@ -127,7 +139,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* The size of the image tiles used to compose the image.
|
* The size of the image tiles used to compose the image.
|
||||||
* Please note that tileSize may be deprecated in a future release.
|
* Please note that tileSize may be deprecated in a future release.
|
||||||
* Instead the getTileSize(level) function should be used.
|
* Instead the getTileSize(level) function should be used.
|
||||||
* @member {Number} tileSize
|
* @member {Number} tileSize
|
||||||
* @memberof OpenSeadragon.TileSource#
|
* @memberof OpenSeadragon.TileSource#
|
||||||
@ -148,12 +160,16 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
|||||||
* @memberof OpenSeadragon.TileSource#
|
* @memberof OpenSeadragon.TileSource#
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @member {Boolean} ready
|
* @member {Boolean} ready
|
||||||
* @memberof OpenSeadragon.TileSource#
|
* @memberof OpenSeadragon.TileSource#
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( 'string' == $.type( arguments[ 0 ] ) ){
|
if( 'string' == $.type( arguments[ 0 ] ) ){
|
||||||
|
this.url = arguments[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.url) {
|
||||||
//in case the getImageInfo method is overriden and/or implies an
|
//in case the getImageInfo method is overriden and/or implies an
|
||||||
//async mechanism set some safe defaults first
|
//async mechanism set some safe defaults first
|
||||||
this.aspectRatio = 1;
|
this.aspectRatio = 1;
|
||||||
@ -165,7 +181,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
|||||||
this.ready = false;
|
this.ready = false;
|
||||||
//configuration via url implies the extending class
|
//configuration via url implies the extending class
|
||||||
//implements and 'configure'
|
//implements and 'configure'
|
||||||
this.getImageInfo( arguments[ 0 ] );
|
this.getImageInfo( this.url );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -185,8 +201,8 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
|||||||
Math.log( 2 )
|
Math.log( 2 )
|
||||||
) : 0
|
) : 0
|
||||||
);
|
);
|
||||||
if( callback && $.isFunction( callback ) ){
|
if( this.success && $.isFunction( this.success ) ){
|
||||||
callback( this );
|
this.success( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +213,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
|||||||
$.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{
|
$.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the tileSize for a given level.
|
* Return the tileSize for a given level.
|
||||||
* Subclasses should override this if tileSizes can be different at different levels
|
* Subclasses should override this if tileSizes can be different at different levels
|
||||||
* such as in IIIFTileSource. Code should use this function rather than reading
|
* such as in IIIFTileSource. Code should use this function rather than reading
|
||||||
* from .tileSize directly. tileSize may be deprecated in a future release.
|
* from .tileSize directly. tileSize may be deprecated in a future release.
|
||||||
@ -355,6 +371,10 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{
|
|||||||
}
|
}
|
||||||
|
|
||||||
options = $TileSource.prototype.configure.apply( _this, [ data, url ]);
|
options = $TileSource.prototype.configure.apply( _this, [ data, url ]);
|
||||||
|
if (options.ajaxWithCredentials === undefined) {
|
||||||
|
options.ajaxWithCredentials = _this.ajaxWithCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
readySource = new $TileSource( options );
|
readySource = new $TileSource( options );
|
||||||
_this.ready = true;
|
_this.ready = true;
|
||||||
/**
|
/**
|
||||||
@ -383,45 +403,50 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// request info via xhr asynchronously.
|
// request info via xhr asynchronously.
|
||||||
$.makeAjaxRequest( url, function( xhr ) {
|
$.makeAjaxRequest( {
|
||||||
var data = processResponse( xhr );
|
url: url,
|
||||||
callback( data );
|
withCredentials: this.ajaxWithCredentials,
|
||||||
}, function ( xhr, exc ) {
|
success: function( xhr ) {
|
||||||
var msg;
|
var data = processResponse( xhr );
|
||||||
|
callback( data );
|
||||||
|
},
|
||||||
|
error: function ( xhr, exc ) {
|
||||||
|
var msg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
IE < 10 will block XHR requests to different origins. Any property access on the request
|
IE < 10 will block XHR requests to different origins. Any property access on the request
|
||||||
object will raise an exception which we'll attempt to handle by formatting the original
|
object will raise an exception which we'll attempt to handle by formatting the original
|
||||||
exception rather than the second one raised when we try to access xhr.status
|
exception rather than the second one raised when we try to access xhr.status
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
msg = "HTTP " + xhr.status + " attempting to load TileSource";
|
msg = "HTTP " + xhr.status + " attempting to load TileSource";
|
||||||
} catch ( e ) {
|
} catch ( e ) {
|
||||||
var formattedExc;
|
var formattedExc;
|
||||||
if ( typeof( exc ) == "undefined" || !exc.toString ) {
|
if ( typeof( exc ) == "undefined" || !exc.toString ) {
|
||||||
formattedExc = "Unknown error";
|
formattedExc = "Unknown error";
|
||||||
} else {
|
} else {
|
||||||
formattedExc = exc.toString();
|
formattedExc = exc.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = formattedExc + " attempting to load TileSource";
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = formattedExc + " attempting to load TileSource";
|
/***
|
||||||
|
* Raised when an error occurs loading a TileSource.
|
||||||
|
*
|
||||||
|
* @event open-failed
|
||||||
|
* @memberof OpenSeadragon.TileSource
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.TileSource} eventSource - A reference to the TileSource which raised the event.
|
||||||
|
* @property {String} message
|
||||||
|
* @property {String} source
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
_this.raiseEvent( 'open-failed', {
|
||||||
|
message: msg,
|
||||||
|
source: url
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
|
||||||
* Raised when an error occurs loading a TileSource.
|
|
||||||
*
|
|
||||||
* @event open-failed
|
|
||||||
* @memberof OpenSeadragon.TileSource
|
|
||||||
* @type {object}
|
|
||||||
* @property {OpenSeadragon.TileSource} eventSource - A reference to the TileSource which raised the event.
|
|
||||||
* @property {String} message
|
|
||||||
* @property {String} source
|
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
||||||
*/
|
|
||||||
_this.raiseEvent( 'open-failed', {
|
|
||||||
message: msg,
|
|
||||||
source: url
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2058,14 +2058,22 @@ function getTileSourceImplementation( viewer, tileSource, successCallback,
|
|||||||
setTimeout( function() {
|
setTimeout( function() {
|
||||||
if ( $.type( tileSource ) == 'string' ) {
|
if ( $.type( tileSource ) == 'string' ) {
|
||||||
//If its still a string it means it must be a url at this point
|
//If its still a string it means it must be a url at this point
|
||||||
tileSource = new $.TileSource( tileSource, function( event ) {
|
tileSource = new $.TileSource({
|
||||||
successCallback( event.tileSource );
|
url: tileSource,
|
||||||
|
ajaxWithCredentials: viewer.ajaxWithCredentials,
|
||||||
|
success: function( event ) {
|
||||||
|
successCallback( event.tileSource );
|
||||||
|
}
|
||||||
});
|
});
|
||||||
tileSource.addHandler( 'open-failed', function( event ) {
|
tileSource.addHandler( 'open-failed', function( event ) {
|
||||||
failCallback( event );
|
failCallback( event );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
} else if ( $.isPlainObject( tileSource ) || tileSource.nodeType ) {
|
} else if ( $.isPlainObject( tileSource ) || tileSource.nodeType ) {
|
||||||
|
if (tileSource.ajaxWithCredentials === undefined) {
|
||||||
|
tileSource.ajaxWithCredentials = viewer.ajaxWithCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $.isFunction( tileSource.getTileUrl ) ) {
|
if ( $.isFunction( tileSource.getTileUrl ) ) {
|
||||||
//Custom tile source
|
//Custom tile source
|
||||||
var customTileSource = new $.TileSource( tileSource );
|
var customTileSource = new $.TileSource( tileSource );
|
||||||
|
Loading…
Reference in New Issue
Block a user