Почему arrayBuffer.slice(0, 2).byteLength == 11?
Я пишу сервис-воркер для PWA, который обрабатывает кешированные аудиофайлы. Я следую этому руководству, чтобы правильно реагировать на выборки, включающие заголовки диапазонов, к которым Safari очень внимателен. У меня есть следующая функция (вызывается из моегоfetch
обработчик событий), который довольно точно следует коду, предложенному в руководстве:
async function respondRangeRequest (request) {
const response = await respondFromCacheOrFetch(request) // fetches the cached response for the resource
const arrayBuffer = await response.arrayBuffer()
const rangeHeader = request.headers.get('range')
const range = /^bytes=(\d+)-(\d+)?$/.exec(rangeHeader)
if (!range) {
console.log(`SW: Invalid range request for ${request.url}`)
return rangeNotSatisfiableResponse()
}
const rangeStart = range[1]
const rangeEnd = range[2] || arrayBuffer.byteLength - 1
console.log(`SW: Range request with header ${rangeHeader}`) // range header is `bytes=0-1`
const responseBuffer = arrayBuffer.slice(rangeStart, rangeEnd + 1)
// copy headers from the original request, except Content-Length and Content-Range which we will replace
const responseHeaders = Array.from(response.headers.entries())
.filter(pair => !['content-range', 'content-length'].includes(pair[0]))
console.log(responseBuffer) // logs an arrayBuffer with byteLength of 11
return new Response(
responseBuffer,
{
status: 206,
statusText: 'Partial Content',
headers: [
...responseHeaders,
['Content-Length', responseBuffer.byteLength], // results in `Content-Length 11`
['Content-Range', `bytes ${rangeStart}-${rangeEnd}/${arrayBuffer.byteLength}`],
],
}
)
}
Согласно комментариям, когда этот код регистрирует заголовок диапазона bytes=0-1
, ответ arrayBuffer, построенный через arrayBuffer.slice(rangeStart, rangeEnd + 1)
имеет byteLength
из 11. Почему это должно быть?
Мой общий ответ заставляет Safari (на iOS) установить бесконечную длительность аудиоэлемента, что приводит к невозможности поиска. Это единственная аномальная часть моего ответа, которую я заметил, поэтому я могу указать только на то, что может пойти не так.
Конечно, если у кого-то есть еще одно предположение, почему мой ответ может не удовлетворять Safari, я был бы очень благодарен за это!
1 ответ
Всем спасибо за то, что вы были моей резиновой уткой. Как только я задал этот вопрос, я просмотрел фрагменты кода в руководстве и заметил, что я пропустил преобразование моих результатов регулярного выражения вNumber
. Я изменил рассматриваемые строки на:
const rangeStart = Number(range[1])
const rangeEnd = Number(range[2]) || arrayBuffer.byteLength - 1
Теперь Safari нравится мой ответ, и я могу искать в своих кэшированных аудиофайлах!
Очевидно, я настраивал свой rangeEnd
к строке "1"
, так что rangeEnd + 1
закончился как "11"
. Я люблю JavaScript.