将 Axios 与 NextJS 15 服务器操作功能结合使用

问题描述 投票:0回答:1

我正在考虑将 Axios 与我的 NextJS 15 应用程序一起使用来上传文件并让它显示上传进度!这还包括多文件上传,我也很想弄清楚上传大文件!我现在的问题是,弄清楚我是否可以在 axios 中调用服务操作函数并在我的上传页面中调用

await uploadFileToS3(file, S3Payload)
函数🤔?!

如:

// app/actions/s3File.ts

"use server"

import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"
import { revalidatePath } from "next/cache"

type S3Payload = {
  uploadDestination: string
  bucket: string
  hostName: string
  uploadEndpoint: string
}

export async function uploadFileToS3( formData: FormData, payload: S3Payload ): Promise<any[]> {
  const s3 = new S3Client({
    ...
  })
  
  const { uploadDestination, bucket, hostName, uploadEndpoint } = payload

  try {
    const files = formData.getAll("file") as File[]
    
    const response = await Promise.all(
      files.map(async (file) => {
        const {name: fileName, type: fileType, lastModified: date, size: fileSize} = file
        const fileExtension = fileType.split("/")\[1\]
        const fileID = `${uploadDestination}\_CUSTOMRANDOMID` as string
        const filePath = `${uploadDestination}/${fileID}.${fileExtension}`
        
        const arrayBuffer = await file.arrayBuffer()
        const buffer = Buffer.from(arrayBuffer)
        
        const uploadFileObject = {
          Bucket: bucket,
          Key: filePath,
          Body: buffer,
          ContentType: fileType,
          ContentLength: fileSize,
        }
        
        const uploadFile = new PutObjectCommand(uploadFileObject)
        const upload = await s3.send(uploadFile)
      })
    )
    
    revalidatePath("/")
    return response
  } catch (error) {
    ...
  }
}

我的上传文件目前如下所示:

// uploadPage/component.tsx

...

import { Dropzone, DropzoneProps, IMAGE_MIME_TYPE } from '@mantine/dropzone';
import { uploadFileToS3 } from "@/app/actions/s3File";

...

async function handleOnSubmit(e: any) {
  setUploading(true)
 
  const files = e
  const uploadDestination = mediaType
  
  try {
    const formData = new FormData()
    
    files.forEach((file) => formData.append("file", file))
    // This is where I think the Axios would come in effect for upload progress?!
    await uploadFileToS3(formData, {
      uploadDestination, // Picture | Video | Audio | ECT
      bucket: process.env.NEXT_PUBLIC_S3_BUCKET_NAME!,
      hostName: process.env.NEXT_PUBLIC_S3_HOST_NAME!,
      uploadEndpoint: `https://${process.env.NEXT\_PUBLIC\_S3\_BUCKET\_NAME!}.${process.env.NEXT\_PUBLIC\_S3\_HOST\_NAME!}`
    })
  } catch (error) {
    console.error("File(s) couldn't be uploaded to S3", error)
  }
}

return <>
  ...

  <Dropzone
    onDrop={(files) => handleOnSubmit(files)}
    onReject={(files) => console.log('rejected files', files)}
    loading={isUploading}
    bg="none"
    radius="md"
    c="white"
    {...props}
  >
    <Group justify="center" gap="2rem" style={{ pointerEvents: 'none' }} py="4rem">
      <Dropzone.Accept>
        <FileUploadIcon variant="twotone" />
      </Dropzone.Accept>
      
      <Dropzone.Reject> 
        <Cancel01Icon variant="twotone" />
      </Dropzone.Reject>
      
      <Dropzone.Idle>
        <CloudUploadIcon variant="twotone" size="5rem" />
      </Dropzone.Idle>
      
      <Stack gap="0" m="0" p="0">  
        <Title c="white" lh="1" fw="900" ff="text" ta={{base: "center", lg: "left"}}>
          {uploadTitle ? uploadTitle : "Upload Media"}
        </Title>
        <Text size="sm" c="grey" lh="1" ta={{base: "center", lg: "left"}}>
      {helperText ? helperText : "Drag and Drop or Click to Upload File(s)."}
        </Text>
       </Stack>
    </Group>  
  </Dropzone>
  <Progress radius="0 0 0 1rem" size="xl" value={uploadProgress} color="primary" mt="0.5rem" animated /> 
  ...
</>

提前致谢!

将 Axios 与我的 NextJS 15 应用程序一起使用来上传文件并让它显示上传进度。

next.js axios
1个回答
0
投票

我也尝试将其添加到

async function handleOnSubmit(e: any)
函数中

files.forEach((file: string | Blob) => {
  formData.append("file", file)
  axios
    .post(
      uploadFileToS3(
        formData,
        s3Payload
      ),
      {
        headers: {
          'x-ms-blob-type': 'BlockBlob',
        },
        maxContentLength: 2e10,
        maxBodyLength: 2e10,
        onUploadProgress: (event: any) => {
           console.log("Hello from event", event)
           setUploadProgress(Math.round((event.loaded / event.total) * 100))
        }
      }
    ).then((response) => {
      console.log(response)
    })
    .catch((error) => {
      if (error.response) {
        console.log(error.response)
        console.log("server responded")
      } else if (error.request) {
        console.log("network error")
      } else {
        console.log(error)
      }
    })
})

这将通过服务器操作上传内容,但不会运行其余操作,例如

onUploadProgress
或已完成的
.then
。它返回
response error
POST https://DEVSERVER/PAGE/[object%20Promise] 404 (Not Found)

© www.soinside.com 2019 - 2024. All rights reserved.