1
0
mirror of https://github.com/videojs/video.js.git synced 2024-11-28 08:58:46 +02:00

Made vjs.get work with xDomain in IE < 10. closes #1095

This commit is contained in:
Erik Skogby 2014-05-13 12:35:40 -07:00 committed by Steve Heffernan
parent d7f840a969
commit 047bd8f618
3 changed files with 107 additions and 23 deletions

View File

@ -17,6 +17,7 @@ CHANGELOG
* Fixed the default flag for captions/subtitles tracks [[view](https://github.com/videojs/video.js/pull/1153)]
* Fixed compilation failures with LESS v1.7.0 and GRUNT v0.4.4 [[view](https://github.com/videojs/video.js/pull/1180)]
* Added better error handling across the library [[view](https://github.com/videojs/video.js/pull/1197)]
* Updated captions/subtiles file fetching to support cross-origin requests in older IE browsers [[view](https://github.com/videojs/video.js/pull/1095)]
--------------------

View File

@ -566,15 +566,19 @@ vjs.createTimeRange = function(start, end){
/**
* Simple http request for retrieving external files (e.g. text tracks)
* @param {String} url URL of resource
* @param {Function=} onSuccess Success callback
* @param {Function=} onError Error callback
* @param {String} url URL of resource
* @param {Function} onSuccess Success callback
* @param {Function=} onError Error callback
* @param {Boolean=} withCredentials Flag which allow credentials
* @private
*/
vjs.get = function(url, onSuccess, onError){
var local, request;
vjs.get = function(url, onSuccess, onError, withCredentials){
var fileUrl, request, urlInfo, winLoc, crossOrigin;
onError = onError || function(){};
if (typeof XMLHttpRequest === 'undefined') {
// Shim XMLHttpRequest for older IEs
window.XMLHttpRequest = function () {
try { return new window.ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch (e) {}
try { return new window.ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch (f) {}
@ -584,32 +588,59 @@ vjs.get = function(url, onSuccess, onError){
}
request = new XMLHttpRequest();
try {
request.open('GET', url);
} catch(e) {
onError(e);
}
local = (url.indexOf('file:') === 0 || (window.location.href.indexOf('file:') === 0 && url.indexOf('http') === -1));
urlInfo = vjs.parseUrl(url);
winLoc = window.location;
// check if url is for another domain/origin
// ie8 doesn't know location.origin, so we won't rely on it here
crossOrigin = (urlInfo.protocol + urlInfo.host) !== (winLoc.protocol + winLoc.host);
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200 || local && request.status === 0) {
onSuccess(request.responseText);
} else {
if (onError) {
onError();
// Use XDomainRequest for IE if XMLHTTPRequest2 isn't available
// 'withCredentials' is only available in XMLHTTPRequest2
// Also XDomainRequest has a lot of gotchas, so only use if cross domain
if(crossOrigin && window.XDomainRequest && !('withCredentials' in request)) {
request = new window.XDomainRequest();
request.onload = function() {
onSuccess(request.responseText);
};
request.onerror = onError;
// these blank handlers need to be set to fix ie9 http://cypressnorth.com/programming/internet-explorer-aborting-ajax-requests-fixed/
request.onprogress = function() {};
request.ontimeout = onError;
// XMLHTTPRequest
} else {
fileUrl = (urlInfo.protocol == 'file:' || winLoc.protocol == 'file:');
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200 || fileUrl && request.status === 0) {
onSuccess(request.responseText);
} else {
onError(request.responseText);
}
}
}
};
};
}
// open the connection
try {
// Third arg is async, or ignored by XDomainRequest
request.open('GET', url, true);
// withCredentials only supported by XMLHttpRequest2
if(withCredentials) {
request.withCredentials = true;
}
} catch(e) {
onError(e);
return;
}
// send the request
try {
request.send();
} catch(e) {
if (onError) {
onError(e);
}
onError(e);
}
};
@ -656,6 +687,48 @@ vjs.getAbsoluteURL = function(url){
return url;
};
/**
* Resolve and parse the elements of a URL
* @param {String} url The url to parse
* @return {Object} An object of url details
*/
vjs.parseUrl = function(url) {
var div, a, addToBody, props, details;
props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
// add the url to an anchor and let the browser parse the URL
a = vjs.createEl('a', { href: url });
// IE8 (and 9?) Fix
// ie8 doesn't parse the URL correctly until the anchor is actually
// added to the body, and an innerHTML is needed to trigger the parsing
addToBody = (a.host === '' && a.protocol !== 'file:');
if (addToBody) {
div = vjs.createEl('div');
div.innerHTML = '<a href="'+url+'"></a>';
a = div.firstChild;
// prevent the div from affecting layout
div.setAttribute('style', 'display:none; position:absolute;');
document.body.appendChild(div);
}
// Copy the specific URL properties to a new object
// This is also needed for IE8 because the anchor loses its
// properties when it's removed from the dom
details = {};
for (var i = 0; i < props.length; i++) {
details[props[i]] = a[props[i]];
}
if (addToBody) {
document.body.removeChild(div);
}
return details;
};
// if there's no console then don't try to output messages
// they will still be stored in vjs.log.history
var _noop = function(){};

View File

@ -243,6 +243,16 @@ test('should get an absolute URL', function(){
ok(vjs.getAbsoluteURL('https://asdf.com/index.html') === 'https://asdf.com/index.html');
});
test('should parse the details of a url correctly', function(){
equal(vjs.parseUrl('#').protocol, window.location.protocol, 'parsed relative url protocol');
equal(vjs.parseUrl('#').host, window.location.host, 'parsed relative url host');
equal(vjs.parseUrl('http://example.com').protocol, 'http:', 'parsed example url protocol');
equal(vjs.parseUrl('http://example.com').hostname, 'example.com', 'parsed example url hostname');
equal(vjs.parseUrl('http://example.com:1234').port, '1234', 'parsed example url port');
});
test('vjs.findPosition should find top and left position', function() {
var d = document.createElement('div'),
position = vjs.findPosition(d);