[ DUVIDA ] - File Upload Multipart usando NEXT.js

Fala gente.

Então, to trabalhando em um projeto que faz envio de arquivos para a CloudFlare R2 usando a api do AWS S3.

A parte de envio de arquivo com tamanho pequeno já está pronta e funcionando perfeitamente, porém, para envio de arquivos grandes (200MB por exemplo), é necessário usar o multipart, ou seja, enviando partes do arquivo com no mínimo 5MB por parte.

Fazendo o upload das partes com requisição HTTP pelo lado do cliente, você precisa ter acesso ao header "ETag", disponível no retorno de quando a parte foi enviada. O problema é que no NEXT.js ele não está dando acesso aos headers no lado do cliente. Eu fiz até pelo lado do servidor para testar, enviando somente a parte de envio com 5MB, e funcionou perfeitamente, porém, na vercel, não posso enviar arquivos para o servidor com um tamanho maior que 4.5MB.

Alguem consegue ajudar?

export default async function uploadPart(file: File, url: string, start: number, end: number) {
    const blob = file.slice(start, end); // Obter parte do arquivo

    const response = await fetch(url, {
        method: "PUT",
        body: blob,
    });

    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }

    return response.headers.get("ETag"); // Retornar ETag para uso na conclusão do upload
}

Oi JP, boa noite !

Eu recentemente implementei um feat sobre upload de vídeos para o provedor pandaVideos, nesse eu usei o protocolo Tus.

Tem algumas libs que são baseadas nesse protocolo que podem ser uma alternativa pro seu caso.

Oi Cesar, tudo bem? Poderia me dizer como posso fazer? Tem alguma pesquisa especifica pra eu fazer?
Mano, primeiramente queria me desculpar pela resposta vaga, passo muito tempo no reddit kkkkk Bom vamos lá, eu fiz a implementação com o a biblioteca @uppy, é um campo drag-and-drop, se não for o seu caso, a implementação pode ser útil. O dashboard config eu copiei da documentação. https://www.npmjs.com/package/uppy https://uppy.io/docs/quick-start/ ```typescript import { useContext, useRef } from "react"; import getToken from "shared/infra/services/auth/getToken"; import Uppy from "@uppy/core"; import "@uppy/core/dist/style.min.css"; import "@uppy/dashboard/dist/style.min.css"; import "@uppy/drag-drop/dist/style.min.css"; import "@uppy/progress-bar/dist/style.min.css"; import { Dashboard } from "@uppy/react"; import "@uppy/status-bar/dist/style.min.css"; import Tus from "@uppy/tus"; import dashboardConfig from "./config/dashboardConfig"; type ThemeType = "auto" | "dark" | "light"; const allowedFileTypes = [ ".MP4", ".MOV", ".WMV", ".AVI", ".AVCHD", ".FLV", ".F4V", ".SWF", ".MKV", ".WEBM", ]; const Uploader = ({ onUploadComplete }) => { const theme = localStorage.getItem("theme_mode") as ThemeType; const token = getToken(); const uppyRef = useRef( new Uppy({ restrictions: { allowedFileTypes, maxNumberOfFiles: 20, }, }), ); const uppyTusUpload = uppyRef.current .use(Tus, { id: `Tus-${Math.random()}`, endpoint, async onBeforeRequest(req, file) { req.setHeader("Filename", encodeURIComponent(file.name)); req.setHeader("Length", file.size.toString()); req.setHeader("Authorization", `Bearer ${token}`); } }) .once("upload-success", () => { setTimeout(async () => { await onUploadComplete(); }, 5000); }); return ( ); }; export default Uploader; ```
Po cara, ajudou muito, valeu demais. Vou dar uma olhada aqui e ver a implementação como fica.