首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TypeError:无法将未定义或null转换为对象React (S3多部分文件上载)

TypeError:无法将未定义或null转换为对象React (S3多部分文件上载)
EN

Stack Overflow用户
提问于 2018-11-08 11:11:15
回答 1查看 1.1K关注 0票数 1

我试图通过使用S3多部分上传方法将图像/视频文件上传到S3桶中。在此之后,我找到了ReactS3Uploader npm包。在使用我的React组件导入这个包之后,我继续获得TypeError:无法将未定义或null转换为对象错误消息,同时从浏览器中选择一个文件。

错误消息:

代码语言:javascript
复制
        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

这是我的代码样本

代码语言:javascript
复制
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(/[^\w\d_\-.]+/ig, '')}
          server="http://cross-origin-server.com"
          inputRef={cmp => this.uploadInput = cmp}
          autoUpload={true}
       />
    </div>
  );
}
}

export default App;

Package.json:

代码语言:javascript
复制
   {
    "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"
    ]
  }

提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2018-11-11 11:18:45

如果不对react-s3-uploader-multipart模块的源代码进行一些修改,就不能使用它。

您可以看到,记录到控制台的错误是由于s3Upload.js第63行上的对象赋值造成的。

代码语言:javascript
复制
var evaporateOptions = Object.assign(this.evaporateOptions, {
    signerUrl: this.signingUrl
});

发生这种情况的原因是,当S3UploadReactS3Upload.js第65行中被调用时,它不会转发在创建ReactS3Uploader React元素时必须设置的evaporateOptions属性。

代码语言:javascript
复制
    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
    });

第68项第103行 of s3upload.js中,this.s3Path也是undefined,而在这些行中的属性访问应该是this.s3path

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

如果进行此更改,则必须将evaporateOptions作为道具传递。例如:

代码语言:javascript
复制
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进行签名。请参阅此特快路线以获得如何实现该功能的示例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53206566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档