web-dev-qa-db-ja.com

redux-formを使用した画像のアップロード

動作してデータをAPIにポストバックするreact.js redux-formがありますが、送信者がフォームを使用して画像をアップロードできるようにする必要もあります。少し苦労して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変数はAPIにPOSTされますが、これはすばらしいことですが、次のものが含まれています。

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

誰かが実際のバイナリデータをその変数にどのように取り込むかを提案できますか?

完全なコードはこちらから入手できます https://github.com/rushughes/dsloracle/blob/master/client/src/components/LandCreate/index.js

11
RusHughes

私は最近同様の問題があり、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;_に簡略化できます

3
Liam Kenneth

file-upload機能の手順は次のとおりです:(APIで画像データを処理する方法)

  • Redux-formの値を FormData インスタンスに追加します。

    let formData = new FormData();
    formData.append('myFile', files[0]);
    
  • axios またはfetchライブラリを使用して、クライアントからAPIにmultipart/form-dataリクエストを送信します。

  • そのmultipart/form-dataリクエストをAPIで受け取り、それを multer で処理してから、ファイルをdisk storageまたはmemory 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
gokcand

Dropzoneを使用してReact.jsで利用できるソリューションがあります。以下を参照してください。

http://reactdropzone.azurewebsites.net/example/

ここで見つけることができるコード: https://react.rocks/example/React-Dropzone

さらに、これらの解決策は、問題から抜け出すために何らかの方法であなたを助けるでしょう:

https://github.com/react-dropzone/react-dropzone

https://medium.com/technoetics/handling-file-upload-in-reactjs-b9b95068f6b

http://blog.mauriziobonani.com/dropzone.js-react.js-and-fluxxor-integration/

https://css-tricks.com/image-upload-manipulation-react/

https://www.reddit.com/r/reactjs/comments/6k6fjr/reactdropzone_integration_with_react/

1
Muhammad Hannan

Node serverで画像のアップロードを処理する

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
});

これはノードエクスプレスの例ですが、手ごわい例のようにノードhttpを使用できます

0
zarcode