TypeError:无法将undefined或null转换为对象React JS(S3多部分文件上传)



我正在尝试使用S3多部分上传方法将图像/视频文件上传到S3 bucket中。之后,我发现ReactS3Uploadernpm包。在使用我的React组件导入此包后,我不断收到类型错误:从浏览器中拾取文件时,无法将未定义或null转换为对象错误消息。

错误消息:

Pre-process: 2.png
Upload progress: 0% Waiting
Uncaught TypeError: Cannot convert undefined or null to object
at Function.assign (<anonymous>)
at S3Upload.push../node_modules/react-s3-uploader-multipart/s3upload.js.S3Upload.uploadToS3 (s3upload.js:64)
at S3Upload.push../node_modules/react-s3-uploader-multipart/s3upload.js.S3Upload.uploadFile (s3upload.js:95)
at S3Upload.<anonymous> (s3upload.js:57)
at S3Upload.preprocess (ReactS3Uploader.js:35)
at S3Upload.push../node_modules/react-s3-uploader-multipart/s3upload.js.S3Upload.handleFileSelect (s3upload.js:55)
at new S3Upload (s3upload.js:47)
at Object.uploadFile (ReactS3Uploader.js:56)
at HTMLUnknownElement.callCallback (react-dom.development.js:147)
at Object.invokeGuardedCallbackDev (react-dom.development.js:196)
at invokeGuardedCallback (react-dom.development.js:250)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:265)
at executeDispatch (react-dom.development.js:571)
at executeDispatchesInOrder (react-dom.development.js:596)
at executeDispatchesAndRelease (react-dom.development.js:695)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js:704)
at forEachAccumulated (react-dom.development.js:676)
at runEventsInBatch (react-dom.development.js:844)
at runExtractedEventsInBatch (react-dom.development.js:852)
at handleTopLevel (react-dom.development.js:5025)
at batchedUpdates$1 (react-dom.development.js:19904)
at batchedUpdates (react-dom.development.js:2246)
at dispatchEvent (react-dom.development.js:5105)
push../node_modules/react-s3-uploader-multipart/s3upload.js.S3Upload.uploadToS3 @ s3upload.js:64
push../node_modules/react-s3-uploader-multipart/s3upload.js.S3Upload.uploadFile @ s3upload.js:95
(anonymous) @ s3upload.js:57
preprocess @ ReactS3Uploader.js:35
push../node_modules/react-s3-uploader-multipart/s3upload.js.S3Upload.handleFileSelect @ s3upload.js:55
S3Upload @ s3upload.js:47
uploadFile @ ReactS3Uploader.js:56
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:265
executeDispatch @ react-dom.development.js:571
executeDispatchesInOrder @ react-dom.development.js:596
executeDispatchesAndRelease @ react-dom.development.js:695
executeDispatchesAndReleaseTopLevel @ react-dom.development.js:704
forEachAccumulated @ react-dom.development.js:676
runEventsInBatch @ react-dom.development.js:844
runExtractedEventsInBatch @ react-dom.development.js:852
handleTopLevel @ react-dom.development.js:5025
batchedUpdates$1 @ react-dom.development.js:19904
batchedUpdates @ react-dom.development.js:2246
dispatchEvent @ react-dom.development.js:5105

这是我的代码示例

import React, { Component } from 'react';
import './App.css';
var ReactS3Uploader = require('react-s3-uploader-multipart');
class App extends Component {
render() {
return (
<div className="App">
<ReactS3Uploader
signingUrl="/s3/sign"
signingUrlMethod="GET"
accept="image/*"
s3path="/uploads/"
preprocess={this.onUploadStart}
onProgress={this.onUploadProgress}
onError={this.onUploadError}
onFinish={this.onUploadFinish}
signingUrlWithCredentials={true}
uploadRequestHeaders={{ 'x-amz-acl': 'public-read' }}  
contentDisposition="auto"
scrubFilename={(filename) => 
filename.replace(/[^wd_-.]+/ig, '')}
server="http://cross-origin-server.com"
inputRef={cmp => this.uploadInput = cmp}
autoUpload={true}
/>
</div>
);
}
}
export default App;

Package.json:

{
"name": "s3",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.6.1",
"react-dom": "^16.6.1",
"react-s3-uploader-multipart": "^4.8.0",
"react-scripts": "2.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}

提前谢谢。

react-s3-uploader-multipart模块在不修改其源代码的情况下无法使用。

您可以看到,记录到控制台的错误是由于s3Upload.js 第63行的对象分配而发生的

var evaporateOptions = Object.assign(this.evaporateOptions, {
signerUrl: this.signingUrl
});

出现这种情况的原因是,当在ReactS3Upload.js的第65行调用S3Upload时,它没有转发创建ReactS3UploaderReact Element时必须设置的evaporateOptions属性。

this.myUploader = new S3Upload({
fileElement: ReactDOM.findDOMNode(this),
signingUrl: this.props.signingUrl,
getSignedUrl: this.props.getSignedUrl,
preprocess: this.props.preprocess,
onProgress: this.props.onProgress,
onFinishS3Put: this.props.onFinish,
onError: this.props.onError,
signingUrlMethod: this.props.signingUrlMethod,
signingUrlHeaders: this.props.signingUrlHeaders,
signingUrlQueryParams: this.props.signingUrlQueryParams,
signingUrlWithCredentials: this.props.signingUrlWithCredentials,
uploadRequestHeaders: this.props.uploadRequestHeaders,
contentDisposition: this.props.contentDisposition,
server: this.props.server,
scrubFilename: this.props.scrubFilename,
s3path: this.props.s3path,
evaporateOptions: this.props.evaporateOptions // this is missing
});

同样在s3upload.js的第68行和第103行中,this.s3Pathundefined,而这些行中的属性访问应该是this.s3path

这让您可以选择创建存储库的分支,进行此更改,并发出一个pull请求,将其合并到上游并部署到npm注册表或者在npm包注册表中查找另一个。

如果您进行了此更改,则蒸发选项必须作为道具传递例如

import crypto from 'crypto';
const config = {
signerUrl: 'auth_upload',
aws_key: 'AKALN0L7ASDFLKJH',
bucket: 'my-big-bucket',
computeContentMd5: true,
cryptoHexEncodedHash256: data => crypto.createHash('sha256').update(data).digest('hex'),
cryptoMd5Method: data => crypto.createHash('md5').update(data).digest('base64')
};
<ReactS3Uploader
accept="image/*"
s3path="uploads/"
signingUrlWithCredentials={true}
uploadRequestHeaders={{ 'x-amz-acl': 'public-read' }}  
contentDisposition="auto"
server="<backend-svc>"
inputRef={ref => (this.uploadInput = ref)}
evaporateOptions={config}
/>

此外,需要在后台服务中实现一个端点来对S3上传URL进行签名。请参阅此/sign快速路由,以获得如何实现的示例。

相关内容

  • 没有找到相关文章

最新更新