[英]Uploading an image with redux-form
I have a react.js redux-form that works and posts data back to my API but I need to also allow the submitter to upload an image with the form, ideally with a preview. 我有一个react.js redux-form,可以工作并将数据发布回我的API,但我还需要让提交者上传带有表单的图像,理想情况下是预览。 I struggled a bit and have arrived at dropzone.js but I can't seem to get my form to actually POST the image data back.
我有点挣扎,已经到达了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>
);
}
The files
variable does get POSTed back to the API which is great but it contains the following: files
变量确实被POST回到API,这很好,但它包含以下内容:
[preview=blob:http://localhost:3000/bed3762e-a4de-4d19-8039-97cebaaca5c1]
Can anyone suggest how I get the actual binary data in to that variable please? 任何人都可以建议我如何获得该变量的实际二进制数据?
The full code is available here https://github.com/rushughes/dsloracle/blob/master/client/src/components/LandCreate/index.js 完整代码可在此处获得https://github.com/rushughes/dsloracle/blob/master/client/src/components/LandCreate/index.js
I recently had a similar issue and solved it by using the FileReader API to convert the blob url to Base64 (can also convert to binary string). 我最近遇到了类似的问题并通过使用FileReader API将blob url转换为Base64(也可以转换为二进制字符串)来解决它。
Then you send the Base64 or binary string to the server. 然后将Base64或二进制字符串发送到服务器。
My example code: 我的示例代码:
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,
}));
}
If you want to send a binary string instead of base64 change reader.readAsDataURL(file);
如果要发送二进制字符串而不是base64更改
reader.readAsDataURL(file);
to reader.readAsBinaryString(file);
to
reader.readAsBinaryString(file);
and this line: const fileAsBase64: any = reader.result.substr(reader.result.indexOf(",") + 1);
这一行:
const fileAsBase64: any = reader.result.substr(reader.result.indexOf(",") + 1);
can be simplified to const file: any = reader.result;
可以简化为
const file: any = reader.result;
file-upload
feature: (How to handle image data in your API) file-upload
功能的步骤:(如何处理API中的图像数据) Append your redux-form values to the FormData instance. 将redux-form值附加到FormData实例。
let formData = new FormData(); formData.append('myFile', files[0]);
Send multipart/form-data
request from Client to your API with axios or fetch
library: 使用axios或
fetch
库从客户端向您的API发送multipart/form-data
请求:
Receive that multipart/form-data
request in your API, process it with multer and then write the file to the disk storage
or memory storage
as follows: 在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 })
(Optional) Serve files directly from your API with Express Serve-Static (可选)使用Express Serve-Static直接从API提供文件
There are solutions available for React.js with Dropzone. Rezone.js有Dropzone可用的解决方案。 Please refer to following:
请参考以下内容:
http://reactdropzone.azurewebsites.net/example/ http://reactdropzone.azurewebsites.net/example/
Which code can be found here: https://react.rocks/example/React-Dropzone 可在此处找到代码: 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://github.com/react-dropzone/react-dropzone
https://medium.com/technoetics/handling-file-upload-in-reactjs-b9b95068f6b
https://medium.com/technoetics/handling-file-upload-in-reactjs-b9b95068f6b
http://blog.mauriziobonani.com/dropzone.js-react.js-and-fluxxor-integration/
http://blog.mauriziobonani.com/dropzone.js-react.js-and-fluxxor-integration/
https://css-tricks.com/image-upload-manipulation-react/
https://css-tricks.com/image-upload-manipulation-react/
https://www.reddit.com/r/reactjs/comments/6k6fjr/reactdropzone_integration_with_react/
https://www.reddit.com/r/reactjs/comments/6k6fjr/reactdropzone_integration_with_react/
Handle image upload with Node server 使用节点服务器处理图像上载
Try catching file in server endpoint function by using formidable 尝试使用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
});
This is node express example, but you can use node http as in formidable example 这是node express示例,但您可以使用节点http作为强大的示例
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.