【问题标题】:Uploading an image with redux-form使用 redux-form 上传图片
【发布时间】:2018-06-15 21:59:45
【问题描述】:

我有一个 react.js redux-form 可以工作并将数据发送回我的 API,但我还需要允许提交者上传带有表单的图像,最好是预览。我有点挣扎,已经到了 dropzone.js,但我似乎无法让我的表单实际 POST 图像数据。

render () {
  const FILE_FIELD_NAME = 'files';

    const renderDropzoneInput = (field) => {
      const files = field.input.value;
      return (
        <div>
          <Dropzone
            name={field.name}
            onDrop={( filesToUpload, e ) => field.input.onChange(filesToUpload)}
          >
            <div>Try dropping some files here, or click to select files to upload.</div>
          </Dropzone>
          {field.meta.touched &&
            field.meta.error &&
            <span className="error">{field.meta.error}</span>}
          {files && Array.isArray(files) && (
            <ul>
              { files.map((file, i) => <li key={i}>{file.name}<img src={file.preview}/></li>) }
            </ul>
          )}
        </div>
      );
    }

    return (
        <form onSubmit={this.props.handleSubmit(this.onSubmit)}>
          <div className="form-group">
            <Field name="files" component={renderDropzoneInput} />
          </div>
          <button type="submit" className="btn btn-default">Submit</button>
        </form>
    );
}

files 变量确实被 POST 回 API,这很棒,但它包含以下内容:

[preview=blob:http://localhost:3000/bed3762e-a4de-4d19-8039-97cebaaca5c1]

谁能建议我如何将实际的二进制数据放入该变量中?

完整的代码在这里https://github.com/rushughes/dsloracle/blob/master/client/src/components/LandCreate/index.js

【问题讨论】:

  • 你能指出你在服务器端接收表单数据的文件吗?

标签: javascript reactjs dropzone.js redux-form


【解决方案1】:

以下是file-upload 功能的步骤:(如何在您的 API 中处理图像数据)

  • 将您的 redux-form 值附加到 FormData 实例。

    let formData = new FormData();
    formData.append('myFile', files[0]);
    
  • 使用axiosfetch 库从客户端向您的API 发送multipart/form-data 请求:

  • 在您的 API 中接收multipart/form-data 请求,使用multer 处理它,然后将文件写入disk storagememory storage,如下所示:

    $ npm install --save multer
    
    const multer  = require('multer')
    
    const storage = multer.diskStorage({
      destination: function (req, file, cb) {
      cb(null, '/tmp/my-uploads')
     },
      filename: function (req, file, cb) {
      cb(null, file.fieldname + '-' + Date.now())
     }
    })
    
    const upload = multer({ storage: storage })
    
    const app = express()
    
    app.post('/upload', upload.single('myFile'), (req, res, next) => {
      // req.file is the `myFile` file
      // req.body will hold the text fields, if there were any
     })
    
  • (可选)使用Express Serve-Static直接从您的 API 提供文件

【讨论】:

    【解决方案2】:

    我最近遇到了类似的问题,通过使用 FileReader API 将 blob url 转换为 Base64(也可以转换为二进制字符串)解决了它。

    然后你将 Base64 或二进制字符串发送到服务器。

    我的示例代码:

    onDrop(acceptedFiles: any): any {
    
        let images: any = this.state.Images;
    
        acceptedFiles.forEach((file: any) => {
    
            const reader: FileReader = new FileReader();
            reader.onload = () => {
                const fileAsBase64: any = reader.result.substr(reader.result.indexOf(",") + 1);
                images.push(fileAsBase64);
            };
    
            reader.onabort = () => console.log("file reading was aborted");
            reader.onerror = () => console.log("file reading has failed");
    
            reader.readAsDataURL(file);
        });
    
        this.setState(prevState => ({   
             Images: images,
        }));
    }
    

    如果您想发送二进制字符串而不是 base64,请将 reader.readAsDataURL(file); 更改为 reader.readAsBinaryString(file);

    这一行:const fileAsBase64: any = reader.result.substr(reader.result.indexOf(",") + 1); 可以简化为const file: any = reader.result;

    【讨论】:

    • 太好了,感谢您的帮助,这个奇怪的技巧让我重回成功之路。本周你是我的个人英雄!非常感谢利亚姆! ?
    • 有什么理由发送 base64(多 33% 的数据)而不是纯二进制?
    【解决方案3】:
    猜你喜欢
    • 2015-10-11
    • 2017-02-03
    • 2011-03-22
    • 2012-12-19
    • 2019-08-12
    • 2021-03-19
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    相关资源
    最近更新 更多