fix(download): ensure rangefetcher loads before abstractfile; skip queryString for blob; add Range probe

This commit is contained in:
2025-12-06 20:11:47 +08:00
parent 061f903074
commit 0b8d5e80db
3 changed files with 30 additions and 5 deletions

View File

@@ -36,10 +36,10 @@ var assets = {
"account.js",
"lyrics.js",
"customsongs.js",
"rangefetcher.js",
"abstractfile.js",
"idb.js",
"plugins.js",
"rangefetcher.js",
"search.js"
],
"css": [

View File

@@ -576,7 +576,8 @@ class Loader{
}
loadScript(url){
var script = document.createElement("script")
var url = url + this.queryString
var isBlob = typeof url === "string" && (url.startsWith("blob:") || url.startsWith("data:"))
var url = isBlob ? url : (url + this.queryString)
var promise = pageEvents.load(script)
script.src = url
document.head.appendChild(script)

View File

@@ -47,11 +47,26 @@ var RangeFetcher = {
r.send()
})
},
_probeRange: function(url){
return new Promise(function(resolve){
var r = new XMLHttpRequest()
r.open("GET", url)
r.responseType = "arraybuffer"
r.setRequestHeader("Range", "bytes=0-0")
r.onload = function(){
var ok = r.status === 206 && !!r.getResponseHeader("Content-Range")
resolve(ok)
}
r.onerror = function(){ resolve(false) }
r.send()
})
},
_runConcurrent: function(tasks, limit){
return new Promise(function(resolve, reject){
var i = 0
var running = 0
var results = []
var done = 0
function next(){
while(running < limit && i < tasks.length){
var idx = i++
@@ -59,7 +74,8 @@ var RangeFetcher = {
tasks[idx]().then(function(res){
results[idx] = res
running--
if(results.length === tasks.length && results.every(function(v){return v !== undefined})){ resolve(results) }
done++
if(done === tasks.length){ resolve(results) }
else{ next() }
}, function(e){ reject(e) })
}
@@ -73,9 +89,17 @@ var RangeFetcher = {
var minChunk = opts.chunkSize || 1048576
var self = this
return this._head(url).then(function(info){
if(!info.length || !info.acceptRanges || info.length < minChunk){
if(!info.length || info.length < minChunk){
return self._getAll(url, "arraybuffer")
}
if(!info.acceptRanges){
return self._probeRange(url).then(function(supported){
if(!supported){
return self._getAll(url, "arraybuffer")
}
return supported
})
}
var total = info.length
var parts = Math.ceil(total / minChunk)
parts = Math.max(1, Math.min(parts, 16))
@@ -103,4 +127,4 @@ var RangeFetcher = {
fetchText: function(url, opts){
return this.fetchBlob(url, opts).then(function(blob){ return blob.text() })
}
}
}