使用XMLHttpRequest和auth摘要部分地响应本机上载文件

Dir*_*don 11 javascript upload blob xmlhttprequest react-native

我正在尝试在服务器上使用XMLHttpRequest()上传本地 mp4 / move文件。这是用react-native编写的,在最终版本中,用户可以将任何大文件从其IOS / Android设备上传到服务器。

该文件约为1 GB(可能从100 mb到10 GB)。

对于70 mb以下的文件,我可以轻松地使用以下代码(如下)加载blob,然后将其切成薄片并使用以下命令放在服务器上:https : //github.com/inorganik/digest-auth-request

sendRequest = new digestAuthRequest('PUT', uri, usernameVal, passwordVal);
        sendRequest.request(function (data) {
let oReq = new XMLHttpRequest();
oReq.open("GET", obj['path'], true);
oReq.responseType = "blob";
oReq.onload = function (oEvent) {
let blob = oReq.response;
console.log(blob);
sendBloblPart()
};
Run Code Online (Sandbox Code Playgroud)

然后,这是sendBlobPart函数,它取消了回调的所有处理(此处不重要):

function sendBloblPart() {
    sendRequest = new digestAuthRequest('PUT', uri, usernameVal, passwordVal);
    sendRequest.request(function (data) {
    }, mainThis.fileUploadErrorHandler, blob.slice(startB, endB), true);
}
Run Code Online (Sandbox Code Playgroud)

我正在从所有部分重构服务器上的文件,这与XMLHttpRequest()创建的blob配合得很好,但是XMLHttpRequest似乎正在将整个文件加载到内存中,因此例如当尝试将1 GB文件加载为blob时我就退出了内存错误,然后我寻找了几种解决方案,但到目前为止没有任何效果,我发现了很有希望的功能:https : //github.com/joltup/react-native-fetch-blob

因此从1 GB文件创建Blob现在大约需要100毫秒,并且不会消耗内存:

const Blob = RNFetchBlob.polyfill.Blob
let newBlob = new Blob(RNFetchBlob.wrap(obj['path']), {type: obj['mime']});
Run Code Online (Sandbox Code Playgroud)

但是新的Blob与以前的Blob具有不同的结构(使用XMLHttpRequest的前一个Blob,我能够简单地将切片的Blob作为要发送的数据进行传递,并且工作得很好,现在无论我如何处理新的Blob我都无法发送在服务器上的任何日期,所有请求都可以正常工作,但是在服务器端接收到0个字节。

谁能提供任何提示/解决方案或想法,以解决这个问题?

在下面,我将添加两个Blob的结构,我可以看到它们是完全不同的(在本示例中,我使用1.2 mb文件,因此XML请求可以正常工作,并且不会像我的1GB所需文件那样崩溃):

两个斑点的结构

当我考虑使用readStream和类似的解决方案时,例如,我找不到流在上传完成或从文件的50%开始等待的选项。

AJc*_*dez 1

我有几个想法。如果您在进行上传调用之前等待 Blob 切片创建,会发生什么情况?

const firstBlob = await new Promise(resolve => {
  newBlob.slice(0, 262144).onCreated(resolve)
});

// send request with blob

firstBlob.safeClose();

const secondBlob = await new Promise(resolve => {
  newBlob.slice(262144, 262144 * 2).onCreated(resolve)
});

// etc
Run Code Online (Sandbox Code Playgroud)

看起来 rn-fetch-blob 包有一个 XHR 的填充,它考虑了 onCreated 回调。如果您使用 XHR,它也可以工作。

const XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
Run Code Online (Sandbox Code Playgroud)