我正在尝试使用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
时,它没有转发创建ReactS3Uploader
React 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.s3Path
是undefined
,而这些行中的属性访问应该是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
快速路由,以获得如何实现的示例。