[英]How to send a Png or Jpeg image as binary to node.js server from react app?
我正在尝试将文件从反应 Web 应用程序发送到 node.js 服务器。
我从文件类型的 html 输入开始,一旦用户上传他们的文件,我就会向我的 Node.js 服务器触发一个发布请求。
一旦进入我的 Node.js 服务器,我需要向第 3 方 API (Twilio) 发送一个发布请求
第 3 方 API 需要我的文件作为二进制数据。
注意:来自文档“POST 的正文或内容必须是二进制格式的文件本身。”
这是下面的 React 组件
import React, { Fragment, useState, useRef } from "react";
import { Col, Button, Media, Card, CardBody } from "reactstrap";
import { useSelector, useDispatch } from "react-redux";
import { attachMMS } from "../../../actions/index";
import cloudUpload from "../../../assets/img/icons/cloud-upload.svg";
const InsertMMS = ({
showFileModal,
setShowFileModal,
showInsertMMSModal,
setShowInsertMMSModal,
uploadMMS,
setUploadMMS,
}) => {
const InputFile = useRef(null);
const [userMMS, setUserMMS] = useState();
const [highlighted, setHighlighted] = useState(false);
const dispatch = useDispatch();
const attachMMSCreate = useSelector((state) => state.attachMMSCreate);
const manualMMSUpload = (e) => {
console.log("manualMMSUpload ran");
e.preventDefault();
if (e.target.files[0].name) {
console.log("file", e.target.files[0]);
getBinary(e.target.files[0]);
setUserMMS(e.target.files[0].name);
}
};
const getBinary = (file) => {
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = () => {
setUploadMMS({ file: file, fileType: file.type });
};
};
const handleInputChange = ({ value, name }) =>
setUploadMMS({ ...uploadMMS, [name]: value });
const onButtonClick = (e) => {
e.preventDefault();
InputFile.current.click();
};
return (
<Fragment>
<Card>
<CardBody className="fs--1 font-weight-normal p-4">
<h4 className="mb-1 mt-3 text-center"></h4>
<div>
<input
type="file"
onChange={(e) => manualMMSUpload(e)}
accept=".gif, .png, .jpeg"
ref={InputFile}
className="d-none"
/>
<div
className={`mb-2 p-3 border-dashed border-2x border-300 bg-light rounded-soft text-center cursor-pointer ${
highlighted ? " border-800" : ""
}`}
onClick={(e) => onButtonClick(e)}
onDragEnter={() => {
setHighlighted(true);
}}
onDragLeave={() => {
setHighlighted(false);
}}
onDragOver={(e) => {
e.preventDefault();
}}
onDrop={(e) => {
e.preventDefault();
}}
>
<Fragment>
<Media className=" fs-0 mx-auto d-inline-flex align-items-center">
<img src={cloudUpload} alt="" width={25} className="mr-2" />
<Media>
<p className="fs-0 mb-0 text-700">
{userMMS ? userMMS : "Upload your File"}
</p>
</Media>
</Media>
<p className="mb-0 w-75 mx-auto text-500">
Supports: .gif, .png, .jpeg{" "}
</p>
</Fragment>
</div>
</div>
<p className="fs-0 text-center">multi-media message</p>
<Col className="text-center">
<Button
disabled={!uploadMMS}
color="primary"
onClick={() => {
return (
dispatch(attachMMS(uploadMMS)),
setShowInsertMMSModal(!showInsertMMSModal),
setShowFileModal(!showFileModal)
);
}}
className="my-3 text-white"
>
{attachMMSCreate.loading ? "...processing" : "Attach MMS"}
</Button>
</Col>
</CardBody>
</Card>
</Fragment>
);
};
export default InsertMMS;
这是从 React 向 Node.js 服务器发出 POST 请求时调用的 Action
export const attachMMS = (uploadMMS) => async (dispatch) => {
console.log("body of attachMMS in actions", uploadMMS);
try {
dispatch({ type: ATTACH_MMS_CREATE_REQUEST });
await axios({
url: "http://localhost:5000/mms",
method: "POST",
data: uploadMMS.file,
withCredentials: true,
}).then((res) =>
dispatch({ type: ATTACH_MMS_CREATE_SUCCESS, payload: res })
);
} catch (error) {
console.log(error);
dispatch({
type: ATTACH_MMS_CREATE_FAIL,
payload:
error.message && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
这是被触发的 Node.js 路由
module.exports = (router) => {
router.route("/mms").post(twilCtrl.createMediaMMSResource);
};
这是被调用的 Node.js 函数
const createMediaMMSResource = async (req, res) => {
try {
const { subActServiceSid, subActAuthToken, convoServiceSid } = req.user;
let mediaResource;
await axios({
url: `https://mcs.us1.twilio.com/v1/Services/${convoServiceSid}/Media`,
method: "POST",
data: req.body, // this needs to be the file itself in binary format
headers: {
"Content-Type": "image/png",
},
auth: { username: subActServiceSid, password: subActAuthToken },
withCredentials: true,
}).then((res) => {
console.log(
"res from first post request to twilio with fileData",
res.data
);
return (mediaResource = {
mediaUrl: res.data.url,
serviceSid: res.data.service_sid,
mediaSid: res.data.sid,
});
});
res.status(201).json(mediaResource);
} catch (err) {
console.log(err);
}
};
这是我从客户那里得到的回复......
有没有人看到这个问题? 我似乎无法理解如何将“二进制”数据发送到 node.js 服务器.....
可以从浏览器发送二进制数据,您可以通过express.raw()
中间件在 Express 中处理这些数据,但是我会改为执行以下操作...
通过FormData
将文件上传到您的 Express 服务。 这通常是浏览器执行二进制上传的方式,而 Axios 等实用程序使其变得更加容易。
const manualMMSUpload = (e) => { if (e.target.files.length > 0) { const file = e.target.files[0]; setUploadMMS({ file, fileType: file.type }); setUserMMS(file.name); } };
// export const attachMMS = (uploadMMS) => async (dispatch) => { // ... // use axios.postForm() const res = await axios.postForm("http://localhost:5000/mms", { file: uploadMMS.file }, { withCredentials: true }); // do you actually need cookies? dispatch({type: ATTACH_MMS_CREATE_SUCCESS, payload: res}) // ...
仅供参考,除非您依赖 cookie,否则您不需要withCredentials
。
如果您使用的是没有postForm
的旧版本 Axios,请使用以下命令
const data = new FormData(); data.append("file", uploadMMS.file); const res = await axios.post("http://localhost:5000/mms", data);
使用Multer或express-fileupload中间件在 Express 服务中处理文件上传。
const fileUpload = require('express-fileupload'); router.route('/mms').post(fileUpload(), twilCtrl.createMediaMMSResource)
将上传的文件缓冲区传递给上游 API。
const response = await axios.post( `https://mcs.us1.twilio.com/v1/Services/${convoServiceSid}/Media`, req.files.file.data, // here's the buffer { auth: { username: subActServiceSid, password: subActAuthToken }, headers: { "content-type": req.files.file.mimetype, }, } );
这应该将文件数据缓冲区作为原始二进制数据上传。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.