Polyfill для загрузки загрузки, без потока - PullRequest
0 голосов
/ 03 декабря 2018

Я столкнулся с проблемой Fetch API не поддерживает прогресс.Я прочитал соответствующие темы , и ReadableStreams выглядит хорошим кандидатом, однако мы не можем использовать его из-за нашей политики зависимостей (все еще на ранней стадии и должны быть заполнены во многих браузерах ).

Итак, нам понадобился полифил, построенный на недавно доступных API, скорее всего, XHR.Я хотел бы поделиться нашей реализацией.Это не очень сложно, но может сэкономить время для других.

1 Ответ

0 голосов
/ 03 декабря 2018

Вот наше решение, которое опирается на XHR, пытаясь держаться поближе к подписи выборки.Обратите внимание, что здесь основное внимание уделяется прогрессу, статусу ответа и данным ответа.

interface OnProgress {
    (loaded: number, total: number, done: boolean): void;
}

export function fetch(url: string, { method, headers, body }, onProgress: OnProgress): Promise {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open(method, url, true);
        xhr.upload.addEventListener('progress', e => onProgress(e.loaded, e.total, false));
        xhr.upload.addEventListener('loadend', _ => onProgress(undefined, undefined, true));
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4)
                resolve();
        };
        xhr.onerror = err => reject(err);
        Object.entries(headers).forEach(([name, value]) => xhr.setRequestHeader(name, value));
        xhr.send(body);
    });
}

Пример использования:

import { fetch } from 'my-fetch-progress';

const formData = new FormData();
formData.append('file', file, file.name);
const onProgress = (loaded, total, done) => console.log('onProgress', loaded, total, done);

fetch('/my-upload', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ...` },
    body: formData
}, onProgress)
    .then(_ => /*...*/);
...