{"record":{"id":"df3610118e8f7238","repo":"bilibili/flv.js","slug":"your-browser-doesn-t-support-xhr-with-arraybuffer","errorCode":null,"errorMessage":"Your browser doesn't support xhr with arraybuffer responseType!","messagePattern":"Your browser doesn't support xhr with arraybuffer responseType!","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"src/io/io-controller.js","lineNumber":251,"sourceCode":"            this._seekHandler = new config.customSeekHandler();\n        } else {\n            throw new InvalidArgumentException(`Invalid seekType in config: ${config.seekType}`);\n        }\n    }\n\n    _selectLoader() {\n        if (this._config.customLoader != null) {\n            this._loaderClass = this._config.customLoader;\n        } else if (this._isWebSocketURL) {\n            this._loaderClass = WebSocketLoader;\n        } else if (FetchStreamLoader.isSupported()) {\n            this._loaderClass = FetchStreamLoader;\n        } else if (MozChunkedLoader.isSupported()) {\n            this._loaderClass = MozChunkedLoader;\n        } else if (RangeLoader.isSupported()) {\n            this._loaderClass = RangeLoader;\n        } else {\n            throw new RuntimeException('Your browser doesn\\'t support xhr with arraybuffer responseType!');\n        }\n    }\n\n    _createLoader() {\n        this._loader = new this._loaderClass(this._seekHandler, this._config);\n        if (this._loader.needStashBuffer === false) {\n            this._enableStash = false;\n        }\n        this._loader.onContentLengthKnown = this._onContentLengthKnown.bind(this);\n        this._loader.onURLRedirect = this._onURLRedirect.bind(this);\n        this._loader.onDataArrival = this._onLoaderChunkArrival.bind(this);\n        this._loader.onComplete = this._onLoaderComplete.bind(this);\n        this._loader.onError = this._onLoaderError.bind(this);\n    }\n\n    open(optionalFrom) {\n        this._currentRange = {from: 0, to: -1};\n        if (optionalFrom) {","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/bilibili/flv.js/blob/42343088f22619cf014a057b3878fe3d320016a6/src/io/io-controller.js#L233-L269","documentation":"IOController._selectLoader picks the best supported streaming loader: it tries MSE-enhanced fetch, then moz-chunked XHR, then RangeLoader. If none of FetchStreamLoader.isSupported(), MozChunkedLoader.isSupported(), or RangeLoader.isSupported() returns true, it concludes the browser lacks XHR arraybuffer responseType support and throws this RuntimeException.","triggerScenarios":"Calling createLoader/constructor in an environment where fetch ReadableStream is unavailable, XHR overrideMimeType of 'text/plain; charset=x-user-defined' (moz-chunked) is unavailable, and XHR responseType 'arraybuffer' is unsupported — effectively legacy browsers or exotic embedded webviews.","commonSituations":"Old IE (<=9), some Android WebViews/Smart-TV browsers, sandboxed environments stubbing XMLHttpRequest, unit tests running in Node with an incomplete DOM shim, or environments where feature detection is fooled by polyfills.","solutions":["Use a browser with XHR arraybuffer or fetch stream support (evergreen Chrome/Firefox/Safari/Edge)","Check that no polyfill/shim is clobbering window.XMLHttpRequest or window.fetch before constructing the player","In Node-based tests, provide a proper XHR mock that supports responseType 'arraybuffer' and isSupported() detection","Bundle a fallback playback path (e.g. plain <video src> progressive playback) for unsupported browsers"],"exampleFix":"// before\nnew IOController(fetchLoader, config, extraData); // throws in legacy webview\n// after\nif (RangeLoader.isSupported() || FetchStreamLoader.isSupported() || MozChunkedLoader.isSupported()) {\n  new IOController(fetchLoader, config, extraData);\n} else {\n  videoElement.src = progressiveFallbackUrl; // <video> progressive fallback\n}","handlingStrategy":"fallback","validationCode":"const supportsPlayback =\n  (typeof fetch !== 'undefined' && typeof ReadableStream !== 'undefined') ||\n  (typeof XMLHttpRequest !== 'undefined' &&\n    (new XMLHttpRequest().responseType === '' || 'arraybuffer' in new XMLHttpRequest()));\nif (!supportsPlayback) console.warn('no streaming loader supported; use progressive fallback');","typeGuard":"const canStream = () =>\n  typeof window !== 'undefined' &&\n  typeof window.XMLHttpRequest === 'function' &&\n  (RangeLoader.isSupported() || FetchStreamLoader.isSupported() || MozChunkedLoader.isSupported());","tryCatchPattern":"try {\n  const controller = new IOController(loaderClass, config, extraData);\n} catch (e) {\n  if (e instanceof RuntimeException && /arraybuffer responseType/.test(e.message)) {\n    enableProgressiveVideoFallback();\n  }\n}","preventionTips":["Feature-detect before constructing the player and branch to a progressive <video> fallback","Exclude legacy browsers (IE <= 9, old WebViews) in supported-environments docs","Ensure polyfills don't fake XMLHttpRequest in ways that break isSupported() checks","In Node test environments, mock XHR with arraybuffer responseType support"],"tags":["browser-compatibility","xhr","feature-detection"],"backgroundTag":"browser-not-supported","analyzedSha":"42343088f22619cf014a057b3878fe3d320016a6","analyzedAt":"2026-09-01T00:27:28.147Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}