XHRLoader.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import { Cache } from './Cache';
  2. import { DefaultLoadingManager } from './LoadingManager';
  3. /**
  4. * @author mrdoob / http://mrdoob.com/
  5. */
  6. function XHRLoader( manager ) {
  7. this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
  8. }
  9. Object.assign( XHRLoader.prototype, {
  10. load: function ( url, onLoad, onProgress, onError ) {
  11. if ( url === undefined ) url = '';
  12. if ( this.path !== undefined ) url = this.path + url;
  13. var scope = this;
  14. var cached = Cache.get( url );
  15. if ( cached !== undefined ) {
  16. scope.manager.itemStart( url );
  17. setTimeout( function () {
  18. if ( onLoad ) onLoad( cached );
  19. scope.manager.itemEnd( url );
  20. }, 0 );
  21. return cached;
  22. }
  23. // Check for data: URI
  24. var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
  25. var dataUriRegexResult = url.match( dataUriRegex );
  26. // Safari can not handle Data URIs through XMLHttpRequest so process manually
  27. if ( dataUriRegexResult ) {
  28. var mimeType = dataUriRegexResult[1];
  29. var isBase64 = !!dataUriRegexResult[2];
  30. var data = dataUriRegexResult[3];
  31. data = window.decodeURIComponent(data);
  32. if( isBase64 ) {
  33. data = window.atob(data);
  34. }
  35. try {
  36. var response;
  37. var responseType = ( this.responseType || '' ).toLowerCase();
  38. switch ( responseType ) {
  39. case 'arraybuffer':
  40. case 'blob':
  41. response = new ArrayBuffer( data.length );
  42. var view = new Uint8Array( response );
  43. for ( var i = 0; i < data.length; i ++ ) {
  44. view[ i ] = data.charCodeAt( i );
  45. }
  46. if ( responseType === 'blob' ) {
  47. response = new Blob( [ response ], { "type" : mimeType } );
  48. }
  49. break;
  50. case 'document':
  51. var parser = new DOMParser();
  52. response = parser.parseFromString( data, mimeType );
  53. break;
  54. case 'json':
  55. response = JSON.parse( data );
  56. break;
  57. default: // 'text' or other
  58. response = data;
  59. break;
  60. }
  61. // Wait for next browser tick
  62. window.setTimeout( function() {
  63. if ( onLoad ) onLoad( response );
  64. scope.manager.itemEnd( url );
  65. }, 0);
  66. } catch ( error ) {
  67. // Wait for next browser tick
  68. window.setTimeout( function() {
  69. if ( onError ) onError( error );
  70. scope.manager.itemError( url );
  71. }, 0);
  72. }
  73. } else {
  74. var request = new XMLHttpRequest();
  75. request.open( 'GET', url, true );
  76. request.addEventListener( 'load', function ( event ) {
  77. var response = event.target.response;
  78. Cache.add( url, response );
  79. if ( this.status === 200 ) {
  80. if ( onLoad ) onLoad( response );
  81. scope.manager.itemEnd( url );
  82. } else if ( this.status === 0 ) {
  83. // Some browsers return HTTP Status 0 when using non-http protocol
  84. // e.g. 'file://' or 'data://'. Handle as success.
  85. console.warn( 'THREE.XHRLoader: HTTP Status 0 received.' );
  86. if ( onLoad ) onLoad( response );
  87. scope.manager.itemEnd( url );
  88. } else {
  89. if ( onError ) onError( event );
  90. scope.manager.itemError( url );
  91. }
  92. }, false );
  93. if ( onProgress !== undefined ) {
  94. request.addEventListener( 'progress', function ( event ) {
  95. onProgress( event );
  96. }, false );
  97. }
  98. request.addEventListener( 'error', function ( event ) {
  99. if ( onError ) onError( event );
  100. scope.manager.itemError( url );
  101. }, false );
  102. if ( this.responseType !== undefined ) request.responseType = this.responseType;
  103. if ( this.withCredentials !== undefined ) request.withCredentials = this.withCredentials;
  104. if ( request.overrideMimeType ) request.overrideMimeType( 'text/plain' );
  105. request.send( null );
  106. }
  107. scope.manager.itemStart( url );
  108. return request;
  109. },
  110. setPath: function ( value ) {
  111. this.path = value;
  112. return this;
  113. },
  114. setResponseType: function ( value ) {
  115. this.responseType = value;
  116. return this;
  117. },
  118. setWithCredentials: function ( value ) {
  119. this.withCredentials = value;
  120. return this;
  121. }
  122. } );
  123. export { XHRLoader };
粤ICP备19079148号