Estoy usando React con Nodemailer para enviar correos electrónicos desde un formulario de entrada del usuario, el usuario debería poder adjuntar un archivo (un PDF, por ejemplo) a través del formulario y el contenido del formulario se enviará como un correo electrónico usando Nodemailer. Mi problema es que no sé cómo adjuntar el archivo al correo electrónico. Aquí hay una lista y ejemplos de propiedades que se pueden usar usando Nodemailer. ¿Qué propiedades puedo extraer del objeto ingresado a través de la entrada del archivo en event.target.files para usar para adjuntar al correo electrónico? ¿Puedo obtener la ruta del archivo ingresado, por ejemplo?
Código:
const [file, setFile] = useState(null); const handleSubmit = async(e) => { e.preventDefault(); try { await axios.post("http://localhost:4000/send_form", { file }); } catch (error) { console.log(error); } } return ( <form onSubmit={handleSubmit}> <input type="file" onChange={(e) => setFile(e.target.files[0])} required/> <button type="submit">Send</button> </form> );Servidor:
app.post("/send_form", cors(), async (req, res) => { let { file } = req.body; await transport.sendMail({ from: "from@sender.com", to: "to@receiver.com", subject: "Subject", html: `<h1>Hello</h1>`, attachments: [{ filename: "", path: "" }] }) });No necesita axios para cargar el archivo, simplemente PUBLIQUELO como FormData con Fetch API .
async function handleSubmit(event) { event.preventDefault(); let fd = new FormData(); fd.append('myfile', file); fetch('http://localhost:4000/upload', { method: 'POST', body: fd }).catch(err => { console.error(err); }); } Si tiene otros datos para enviar junto con su imagen, también se pueden agregar al objeto FormData .
fd.append('name', 'Joe'); fd.append('age', 40); // etc... O simplemente puede capturar todos los campos de cualquier HTMLFormElement . Solo asegúrese de configurar el atributo enctype para que sea multipart/form-data .
let form = document.querySelector('#your-form'); let fd = new FormData(form);Luego, en el servidor, puede usar el middleware multer para transmitir el búfer del archivo al adjunto del nodemailer:
import express from 'express'; import multer from 'multer'; import transport from './your_app.js' const app = express(); const upload = multer({ storage: multer.memoryStorage() }); app.post('/upload', upload.single('myfile'), (req, res) => { transport.sendMail({ from: "from@sender.com", to: "to@receiver.com", subject: "Subject", html: `<h1>Hello</h1>`, attachments: [{ filename: req.file.originalname, content: req.file.buffer }] }) }); app.listen(4000);Si tiene otro middleware que necesita usar en esta ruta, se pueden pasar como una matriz:
import cors from 'cors'; let middleware = [ cors(), upload.single('myfile') ]; app.post('/upload', middleware, handler); Tenga en cuenta que la clave utilizada en las siguientes dos declaraciones debe coincidir. Esta clave corresponde al atributo de name de la entrada del archivo.
En
handleSubmit():fd.append('myfile', file);En
app.post():upload.single('myfile')
Multer también permite cargar múltiples archivos si es necesario. Puede capturar varios archivos de una sola entrada con el atributo multiple :
upload.array('myfile', 3)O podría usar varias entradas de archivo:
upload.fields([ { name: 'myfile', maxCount: 1 }, { name: 'another-file', maxCount: 8 } ]) Si hace esto, deberá acceder a los datos del archivo cargado desde la propiedad req.files en lugar del req.file singular.
El resto de los datos de su formulario estarán disponibles en el objeto req.body :
req.body.name == 'Joe' req.body.age == 40;Mi problema es que no sé cómo adjuntar el archivo al correo electrónico.
¿Entonces no sabes cómo agregar un código de carga de archivos? Siga este tutorial y de alguna manera podría enviar estos datos a través de HTTP POST a su servidor.
https://www.geeksforgeeks.org/how-to-read-a-local-text-file-using-javascript/