使用 redux async thunk 下载文件

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

我有一个 React Redux 应用程序和一个 Django 服务器。我的 django 服务器有一个端点,我可以从 s3 中提取文件,并对文件进行 Base64 编码并返回编码后的字符串。当我的 redux fetch 操作完成时,我想下载文件,而无需导航到我的 React 应用程序中的新页面。这是代码:

// DocumentReducer.tsx (+ all necessary imports)

export const getDocument = createAsyncThunk("document/download", async (payload: any) => {
  const {id} = payload
  const response = await instance.get(`tables/document/download/${id}`)
  return response.data
})

const documentSlice = createSlice({
  name: "document",
  initialState: initialState,
  reducers:{},
  extraReducers: (builder) => {
    ...
    builder.addCase(getDocument.fulfilled, (state, action) => {
      const file = action.payload.file
      window.location.href = 'data:application/octet-stream;base64,' + file
      state.status = 'fulfilled'
    })
  } 
})
// ExportComponent.tsx (+ all necessary imports)
export const ExportButton: React.FC<ExportButtonProps> = ({document_id}) => {
  const dispatch = useAppDispatch()
  const handleClick = () => {
    const payload = {id: document_id}
    dispatch(getDocument(payload))
  }
  return (
    <Button variant="contained" size="small" onClick={handleClick}>
      <div className="flex gap-3">
        <p>Export</p>
        <ArrowDownTrayIcon className='w-4 text-white'/>
      </div>
    </Button>
  )
}

在服务器端:

# views.py
def encode_document(s3_key):
    """ get document from s3 and base 64 encode the document """
    buffer = BytesIO()
    output_stream = BytesIO()
    S3_CLIENT.download_fileobj("BUCKET_NAME", s3_key, buffer)
    encoded = b64encode(buffer.getvalue()).decode()
    return encoded

class DocumentS3(APIView):
    parser_classes = [JSONParser]
    permission_classes = [IsAuthenticated]

    def get(self, request, document_id):
        document = Document.objects.get(id=document_id)
        encoded = encode_document(document.s3_key)
        print(encoded[:10])
        return Response({"file": encoded}, status=status.HTTP_200_OK)

我的服务器成功返回必要的编码字节。下载链接将我带到未找到的页面。有谁知道如何在 redux 中使这个导航成功?

reactjs redux react-redux base64 redux-thunk
1个回答
0
投票

不要在单页应用程序中执行

window.location.href =
- 常见的解决方案例如是这个答案:如何在React js中下载文件 - 一个限制是,如果我记得的话,下载需要由用户操作启动正确地(例如单击按钮),您不能在后台突然开始下载。

问题并非特定于 React 或 Redux 顺便说一句,当以编程方式启动下载时,任何单页应用程序都会遇到相同的问题。

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