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%开始等待的选项。
我有几个想法。如果您在进行上传调用之前等待 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)