使用 redux-form 上传图片
Uploading an image with redux-form
我有一个 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
React.js 有可用的 Dropzone 解决方案。请参考以下内容:
http://reactdropzone.azurewebsites.net/example/
可以在此处找到哪些代码:
https://react.rocks/example/React-Dropzone
Further more these solutions will also assist you in some way, to get out of the problem:
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/
以下是 file-upload
功能的步骤:(如何处理 API 中的图像数据)
将您的 redux-form 值附加到 FormData 实例。
let formData = new FormData();
formData.append('myFile', files[0]);
使用 axios 或 fetch
库将来自客户的 multipart/form-data
请求发送到您的 API:
在您的 API 中接收 multipart/form-data
请求,使用 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 提供文件
我最近遇到了类似的问题,通过使用 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;
我有一个 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
React.js 有可用的 Dropzone 解决方案。请参考以下内容:
http://reactdropzone.azurewebsites.net/example/
可以在此处找到哪些代码: https://react.rocks/example/React-Dropzone
Further more these solutions will also assist you in some way, to get out of the problem:
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/
以下是 file-upload
功能的步骤:(如何处理 API 中的图像数据)
将您的 redux-form 值附加到 FormData 实例。
let formData = new FormData(); formData.append('myFile', files[0]);
使用 axios 或
fetch
库将来自客户的multipart/form-data
请求发送到您的 API:在您的 API 中接收
multipart/form-data
请求,使用 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 提供文件
我最近遇到了类似的问题,通过使用 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;