Почему 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.

Другие вопросы по тегам