개발자로 전향중

Cloudflare 200MB이상 다이렉트 업로드 본문

React

Cloudflare 200MB이상 다이렉트 업로드

hovinee 2023. 10. 17. 15:17

파일이 캐싱이 되어 같은 파일일 경우 통신은 되지만 서버 전달은 안됨으로 주의!

const App = () => {
  useEffect(() => {
    const uppy = new Uppy({
      debug: true,
      autoProceed: true,
    })

    const onUploadSuccess = (el: string) => (file: File, response: any) => {
      const li = document.createElement('li')
      const a = document.createElement('a')
      a.href = response.uploadURL
      a.target = '_blank'
      a.appendChild(document.createTextNode(file.name))
      li.appendChild(a)

      const uploadedFiles = document.querySelector(el)
      if (uploadedFiles) {
        uploadedFiles.appendChild(li)
      }
    }

    uppy
      .use(DragDrop, { target: '#drag-drop-area' })
      .use(Tus, {
        endpoint: '/api/get-upload-url',
        chunkSize: 150 * 1024 * 1024,
      })
      .use(ProgressBar, { target: '.for-ProgressBar', hideAfterFinish: false })
      .on('upload-success', onUploadSuccess('.uploaded-files ol'))

    const uploadBtn = document.querySelector('button.upload-button')
    if (uploadBtn) {
      uploadBtn.addEventListener('click', () => uppy.upload())
    }
    return () => {
      uppy.close()
    }
  }, [])

  return (
    <div>
      <div id="drag-drop-area" style={{ height: '300px' }} />
      <div className="for-ProgressBar" />
      <button
        className="upload-button"
        style={{ fontSize: '30px', margin: '20px' }}
      >
        Upload
      </button>
      <div className="uploaded-files" style={{ marginTop: '50px' }}>
        <ol></ol>
      </div>
    </div>
  )
}
import { NextRequest, NextResponse } from 'next/server'

export async function POST(req: NextRequest) {
  const corsHeaders = {
    'Access-Control-Expose-Headers': '*',
    'Access-Control-Allow-Headers': '*',
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': '*',
  }
  const CLOUDFLARE_API_TOKEN = ''Cludflare 나 stream 할거야~하면서 생성해야함'
  const CLOUDFLARE_ACCOUNT_ID = '돈주면 대시보드 옆에 친절히 나와잇음'
  const endpoint = `https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/stream?direct_user=true`

  const response = await fetch(endpoint, {
    method: 'POST',
    headers: <HeadersInit>{
      Authorization: `bearer ${CLOUDFLARE_API_TOKEN}`,
      'Tus-Resumable': '1.0.0',
      'Upload-Length': req.headers.get('Upload-Length'),
      'Upload-Metadata': req.headers.get('Upload-Metadata'),
    },
  })

  const destination = response.headers.get('Location')
  console.log(destination, '비디오 업로드 갑니다')
  return new NextResponse('', {
    headers: <HeadersInit>{ ...corsHeaders, Location: destination },
  })
}