@@ -1634,7 +1634,7 @@ TinCan client library
16341634
16351635 // is same port?
16361636 || locationPort !== (
1637- urlParts [ 3 ] !== null ? urlParts [ 3 ] : ( urlParts [ 1 ] === "http:" ? "80" : ( urlParts [ 1 ] === "https:" ? "443" : "" ) )
1637+ ( urlParts [ 3 ] !== null && typeof urlParts [ 3 ] !== "undefined" && urlParts [ 3 ] !== "" ) ? urlParts [ 3 ] : ( urlParts [ 1 ] === "http:" ? "80" : ( urlParts [ 1 ] === "https:" ? "443" : "" ) )
16381638 )
16391639 ) ;
16401640 if ( isXD ) {
@@ -1727,6 +1727,7 @@ TinCan client library
17271727 @return {Object } XHR if called in a synchronous way (in other words no callback)
17281728 */
17291729 sendRequest : function ( cfg ) {
1730+ /*global ActiveXObject*/
17301731 this . log ( "sendRequest" ) ;
17311732 var xhr ,
17321733 finished = false ,
@@ -1741,6 +1742,60 @@ TinCan client library
17411742 self = this
17421743 ;
17431744
1745+ // Setup request callback
1746+ function requestComplete ( ) {
1747+ self . log ( "requestComplete: " + finished + ", xhr.status: " + xhr . status ) ;
1748+ var notFoundOk ,
1749+ httpStatus ;
1750+
1751+ //
1752+ // older versions of IE don't properly handle 204 status codes
1753+ // so correct when receiving a 1223 to be 204 locally
1754+ // http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
1755+ //
1756+ httpStatus = ( xhr . status === 1223 ) ? 204 : xhr . status ;
1757+
1758+ if ( ! finished ) {
1759+ // may be in sync or async mode, using XMLHttpRequest or IE XDomainRequest, onreadystatechange or
1760+ // onload or both might fire depending upon browser, just covering all bases with event hooks and
1761+ // using 'finished' flag to avoid triggering events multiple times
1762+ finished = true ;
1763+
1764+ notFoundOk = ( cfg . ignore404 && httpStatus === 404 ) ;
1765+ if ( httpStatus === undefined || ( httpStatus >= 200 && httpStatus < 400 ) || notFoundOk ) {
1766+ if ( cfg . callback ) {
1767+ cfg . callback ( null , xhr ) ;
1768+ }
1769+ else {
1770+ requestCompleteResult = {
1771+ err : null ,
1772+ xhr : xhr
1773+ } ;
1774+ return requestCompleteResult ;
1775+ }
1776+ }
1777+ else {
1778+ // Alert all errors except cancelled XHR requests
1779+ if ( httpStatus > 0 ) {
1780+ requestCompleteResult = {
1781+ err : httpStatus ,
1782+ xhr : xhr
1783+ } ;
1784+ if ( self . alertOnRequestFailure ) {
1785+ alert ( "[warning] There was a problem communicating with the Learning Record Store. (" + httpStatus + " | " + xhr . responseText + ")" ) ;
1786+ }
1787+ if ( cfg . callback ) {
1788+ cfg . callback ( httpStatus , xhr ) ;
1789+ }
1790+ }
1791+ return requestCompleteResult ;
1792+ }
1793+ }
1794+ else {
1795+ return requestCompleteResult ;
1796+ }
1797+ }
1798+
17441799 // respect absolute URLs passed in
17451800 if ( cfg . url . indexOf ( "http" ) === 0 ) {
17461801 fullUrl = cfg . url ;
@@ -1789,7 +1844,17 @@ TinCan client library
17891844
17901845 this . log ( "sendRequest using XMLHttpRequest - async: " + ( typeof cfg . callback !== "undefined" ) ) ;
17911846
1792- xhr = new XMLHttpRequest ( ) ;
1847+ if ( typeof XMLHttpRequest !== "undefined" ) {
1848+ xhr = new XMLHttpRequest ( ) ;
1849+ }
1850+ else {
1851+ //
1852+ // IE6 implements XMLHttpRequest through ActiveX control
1853+ // http://blogs.msdn.com/b/ie/archive/2006/01/23/516393.aspx
1854+ //
1855+ xhr = new ActiveXObject ( "Microsoft.XMLHTTP" ) ;
1856+ }
1857+
17931858 xhr . open ( cfg . method , fullUrl , ( typeof cfg . callback !== "undefined" ) ) ;
17941859 for ( prop in headers ) {
17951860 if ( headers . hasOwnProperty ( prop ) ) {
@@ -1801,6 +1866,13 @@ TinCan client library
18011866 cfg . data += "" ;
18021867 }
18031868 data = cfg . data ;
1869+
1870+ xhr . onreadystatechange = function ( ) {
1871+ self . log ( "xhr.onreadystatechange - xhr.readyState: " + xhr . readyState ) ;
1872+ if ( xhr . readyState === 4 ) {
1873+ requestComplete ( ) ;
1874+ }
1875+ } ;
18041876 }
18051877 else if ( this . _requestMode === XDR ) {
18061878 this . log ( "sendRequest using XDomainRequest" ) ;
@@ -1832,76 +1904,30 @@ TinCan client library
18321904
18331905 xhr = new XDomainRequest ( ) ;
18341906 xhr . open ( "POST" , fullUrl ) ;
1907+
1908+ xhr . onload = function ( ) {
1909+ requestComplete ( ) ;
1910+ } ;
1911+ xhr . onerror = function ( ) {
1912+ requestComplete ( ) ;
1913+ } ;
18351914 }
18361915 else {
18371916 this . log ( "sendRequest unrecognized _requestMode: " + this . _requestMode ) ;
18381917 }
18391918
1840- // Setup request callback
1841- function requestComplete ( ) {
1842- self . log ( "requestComplete: " + finished + ", xhr.status: " + xhr . status ) ;
1843- var notFoundOk ,
1844- httpStatus ;
1845-
1846- //
1847- // older versions of IE don't properly handle 204 status codes
1848- // so correct when receiving a 1223 to be 204 locally
1849- // http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
1850- //
1851- httpStatus = ( xhr . status === 1223 ) ? 204 : xhr . status ;
1852-
1853- if ( ! finished ) {
1854- // may be in sync or async mode, using XMLHttpRequest or IE XDomainRequest, onreadystatechange or
1855- // onload or both might fire depending upon browser, just covering all bases with event hooks and
1856- // using 'finished' flag to avoid triggering events multiple times
1857- finished = true ;
1858-
1859- notFoundOk = ( cfg . ignore404 && httpStatus === 404 ) ;
1860- if ( httpStatus === undefined || ( httpStatus >= 200 && httpStatus < 400 ) || notFoundOk ) {
1861- if ( cfg . callback ) {
1862- cfg . callback ( null , xhr ) ;
1863- }
1864- else {
1865- requestCompleteResult = {
1866- err : null ,
1867- xhr : xhr
1868- } ;
1869- return requestCompleteResult ;
1870- }
1871- }
1872- else {
1873- // Alert all errors except cancelled XHR requests
1874- if ( httpStatus > 0 ) {
1875- requestCompleteResult = {
1876- err : httpStatus ,
1877- xhr : xhr
1878- } ;
1879- if ( self . alertOnRequestFailure ) {
1880- alert ( "[warning] There was a problem communicating with the Learning Record Store. (" + httpStatus + " | " + xhr . responseText + ")" ) ;
1881- }
1882- if ( cfg . callback ) {
1883- cfg . callback ( httpStatus , xhr ) ;
1884- }
1885- }
1886- return requestCompleteResult ;
1887- }
1888- }
1889- else {
1890- return requestCompleteResult ;
1891- }
1919+ //
1920+ // research indicates that IE is known to just throw exceptions
1921+ // on .send and it seems everyone pretty much just ignores them
1922+ // including jQuery (https://github.com/jquery/jquery/blob/1.10.2/src/ajax.js#L549
1923+ // https://github.com/jquery/jquery/blob/1.10.2/src/ajax/xhr.js#L97)
1924+ //
1925+ try {
1926+ xhr . send ( data ) ;
1927+ }
1928+ catch ( ex ) {
1929+ this . log ( "sendRequest caught send exception: " + ex ) ;
18921930 }
1893-
1894- xhr . onreadystatechange = function ( ) {
1895- self . log ( "xhr.onreadystatechange - xhr.readyState: " + finished + ", xhr.status: " + xhr . status ) ;
1896- if ( xhr . readyState === 4 ) {
1897- requestComplete ( ) ;
1898- }
1899- } ;
1900-
1901- xhr . onload = requestComplete ;
1902- xhr . onerror = requestComplete ;
1903-
1904- xhr . send ( data ) ;
19051931
19061932 if ( ! cfg . callback ) {
19071933 // synchronous
0 commit comments