使用redux-form上传图像

时间:2018-01-06 05:39:48

标签: javascript reactjs dropzone.js redux-form

我有一个react.js redux-form可以工作并将数据发布回我的API,但我还需要让提交者上传一张带有表单的图片,理想情况下是预览。我有点挣扎,已经到达了dropzone.js,但我似乎无法让我的表单实际发回图像数据。

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

4 个答案:

答案 0 :(得分:2)

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

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

    let formData = new FormData();
    formData.append('myFile', files[0]);
    
  • 通过axiosmultipart/form-data库向客户发送fetch个请求:

  • 在您的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投放文件

答案 1 :(得分: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;

答案 2 :(得分:1)

答案 3 :(得分:0)

使用节点服务器处理图片上传

尝试使用formidable

在服务器端点函数中捕获文件
app.post('/upload', function (req, res) { // express endpoint 
    var form = new formidable.IncomingForm();

    form.parse(req, function(err, fields, files) { // "req" is server request object
       fs.rename(files.file.path, "/tmp/" + files.file.name); // move file to desired location
    });

    // handle rest of text fields from req.body if there are any
});

这是node express示例,但您可以使用节点http作为强大的示例