javascript - 文件上传阻止更大的文件

标签 javascript reactjs redux react-redux redux-saga

简介

我想要实现的是一个简单的文件上传,带有 redux-saga 和 react 的进度指示)。我在获取此指示时遇到问题,因为文件上传似乎被阻止了 - 它不应该被阻止。

预期行为

在文件上传开始之前,会触发重新渲染并显示微调器并且窗口不会被阻塞。

当前行为

我现在拥有的是一个带有表格的组件,每行显示一个文件。当用户上传文件时,乐观行会添加一个微调器作为内容。上传文件后,乐观行将被替换为带有文件名等的真实行。当我上传大约 50MB 的文件时,窗口被阻塞,并且在文件上传前不久(大约 0.5 秒前)微调器出现,然后文件已上传,微调器再次消失。


边注

  • 如果您用 new Promise(res => setTimeout(res, 5000)) 替换文件上传,一切正常 => 看起来 xhr/fetch 有问题。
  • 我已经使用 XHR、promises 和 onProgress 回调实现了相同的功能,以确保问题不在于抓取。 实现看起来非常接近:https://gist.github.com/robinfehr/2f4018259bf026a468cc31100fed5c9f 对于此实现,我也遇到了同样的问题 - 一直阻塞到几乎上传结束。
  • 如果我将日志语句放入组件的渲染函数中以查看它是否在文件上传之前重新渲染,我会看到(一旦 block 停止并且文件上传)渲染中的日志语句函数实际上是在文件上传完成之前使用时间戳正确触发的。
  • 在此实现中,我使用相同的 reducer:乐观事件以及还原乐观事件的真实事件,它们通过相同的 reducer(此处称为 fileReducer)。
  • 使用第二个缩减器和串联而不是乐观的还原逻辑有助于更早地显示微调器,但无助于阻塞。因此,中间件似乎也被阻塞调用阻塞了。

saga: (postData 使用 fetch)

function* createDocument(partnerId, { payload, meta }) {
  const siteId = getSiteIdFromRoute();
  const {
    mediaGroupId,
    customArticleId,
    logicalComponentId,
    type,
    name,
    documentSrc,
    meta: metaFromFrontEnd
  } = payload;

  const commonEventId = uuid();
  const hans = {
    optimistic: true
  };
  const payloadBasic = {
    id: commonEventId,
    version: 0,
    aggregate: {
      id: uuid(),
      name: 'document'
    },
    context: {
      name: 'contentManagement'
    },
    payload: {
      name,
      type,
      links: {
        partnerId,
        siteId,
        logicalComponentId,
        customArticleId,
        mediaGroupId
      }
    }
  };

  // creates the optimistic (fake) row with a spinner in the file list component - action marked as optimistic which will be reverted.
  yield put(actions.denormalizeEvent({
    ...payloadBasic,
    name: 'documentCreated',
    optimistic: true,
    payload: {
      ...payloadBasic.payload,
      uploading: true
    }
  }));
  yield fork(executeDocumentUpload, type, siteId, partnerId, documentSrc, payloadBasic);
}

function* executeDocumentUpload(type, siteId, partnerId, documentSrc, payloadBasic) {
  const req = yield call(uploadDocument, type, siteId, partnerId, documentSrc);
  const body = yield req.json();
  const { meta: metaFromFileUpload, id } = body.response;
  // removes the optimistic (fake) row from the file list component and and adds the real row with more file information (optimistic event gets reverted in middleware)
  yield put(actions.sendCommandSuccess({
    ...payloadBasic,
    name: 'createDocument',
    payload: {
      ...payloadBasic.payload,
      meta: metaFromFileUpload
    }
  }));
}

function uploadDocument(type, siteId, partnerId, documentSrc) {
  let url;
  if (type === 'site' || type === 'mediaGroup' || type ===     'logicalComponent') {
    url = `/file/site/${siteId}/document`;
  } else if (type === 'customArticle') {
    url = `/file/partner/${partnerId}/document`;
  }
  return postData(url, documentSrc);
}

最佳答案

问题是我确实将文件作为 base64 编码字符串发送,并使用错误的内容类型设置了请求。

'Content-Type': 'text/plain;charset=UTF-8'

将文件放入 FormData 对象并发送没有提到的内容类型的请求导致非阻塞请求。

关于javascript - 文件上传阻止更大的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42630139/

相关文章:

javascript - Redux:打开和关闭中间件

javascript - ngrx - 一旦分派(dispatch)的操作成功更新商店,如何执行操作?

javascript - Fullpage.js 使用连续滚动或循环时禁用 moveSectionUp

javascript - 为什么最后一个console.log中的listeners数组长度是3而不是2?

javascript - 删除没有类的 jquery 元素

javascript - 在 Material-UI 中使用 React 的 'ref' 属性

javascript - 如何在动态字符串的react js中事件监听器或单击监听器?

android - React Native Eject 但仍然能够使用 React Native 代码

Javascript/jQuery "Dangle"动画

javascript - HTML CSS JS具有响应宽度的多个模式图像