#javascript #android #reactjs #react-native #upload
Вопрос:
Следующий код для загрузки отлично работает на iOS, но на Android он иногда (не каждый раз) возвращает следующую ошибку из-за неправильного размера фрагмента.
Example Error:
400: Invalid request. There were 1527808 byte(s) in the request body. There should have been 3145728 byte(s) (starting at offset 15728640 and ending at offset 18874367) according to the Content-Range header.
при попытке загрузить фрагмент и продолжает возвращать ту же ошибку при повторной попытке загрузить тот же фрагмент, если вся загрузка не будет перезапущена.
Фрагмент, созданный для загрузки, имеет правильный размер, потому что значения в заголовке диапазона содержимого взяты из самого фрагмента. Согласно заголовкам, размер блока был таким, как ожидалось, но при загрузке данные теряются.
Я заметил, что это происходит, когда устройство блокируется или отключается в фоновом режиме во время загрузки.
Я использую RNFS
для чтения фрагментов из файла и RNFetchBlob
для запроса PUT.
function uploadChunk(offset) {
let nextOffset = offset;
const thisRecordingInProgress = isInProgress(); // true or false
const totalBytes = thisRecordingInProgress ? '*' : size; // size = actual file size
// if no offset is specified, fetch it from the server
if (nextOffset === undefined) {
const res = await RNFetchBlob.fetch('PUT', url, {
'Content-Length': '0',
'Content-Range': `bytes */${totalBytes}`,
});
({ nextOffset } = parseResponse(res));
}
// 1. Creating chunk
const chunk = await RNFS.read(path, CHUNK_SIZE, nextOffset, 'base64');
const end = nextOffset Buffer.from(chunk, 'base64').length - 1;
// 2. Upload request
const resp = await RNFetchBlob.config({
IOSBackgroundTask: true,
})
.fetch(
'PUT',
URL,
{
'Content-Length': `${CHUNK_SIZE}`,
'Content-Range': `bytes ${nextOffset}-${end}/${totalBytes}`,
'Content-Type': 'application/octet-stream',
'Transfer-Encoding': 'Chunked',
},
chunk
)
.uploadProgress(written => {
// track upload Progress
});
//
({ nextOffset } = await parseResponse(resp));// parses response from server for next offset
if (nextOffset < 0) {
// Completed
} else {
// Upload next chunk
return uploadChunk(nextOffset);
}
}
Я попытался уменьшить размер куска, но проблема все еще сохраняется. Есть ли что-нибудь, что мне нужно сделать, чтобы это работало в фоновом режиме для Android? Или какие-либо идеи, в чем может быть проблема.
Я был бы очень признателен за любую помощь, которую я могу получить. Спасибо
Обновления:
- Я попытался удалить диапазон содержимого, поскольку он необязателен для «Кодирования передачи»: «Фрагментирован», но это не исправило.
- Попытался сбросить фрагмент —
chunk = undefined
после завершения запроса на загрузку, чтобы освободить память. Проблема все еще не устранена.
Комментарии:
1. Привет. как я догадываюсь, вы пытались удалить
Content-Range
из конфигурации большого двоичного объекта?2. @novonimo Да, я пытался удалить
Content-Range
, так как это необязательно'Transfer-Encoding': 'Chunked'
, но это не исправило.