在线投诉箱开发求助:获取表单数据存为.csi文件并发送至指定邮箱
Hey there! Let's break down how to solve your problem step by step—you're already halfway there with your form, so let's fill in the gaps to get that complaint data saved as a .csi file and sent to your email.
Step 1: Refine Your HTML Form
First off, let's tweak your HTML to make it easier to work with. We'll add name attributes to every input (this is how JavaScript will grab user values) and wrap everything in a <form> tag. Here's the updated code:
<form id="complaintForm"> <p style="font-family: tahoma; font-size:25px; color:#E25937;">Do you have a Complaint ?, We're Happy to Hear it :</p> <table> <tr> <td><b><label style="font-family: tahoma; font-size:25px; color:#E25937;">Name : </label></b></td> <td><input type="text" name="name" style="font-family: tahoma; font-size:25px; color:#E25937;"></td> </tr> <tr> <td><b><label style="font-family: tahoma; font-size:25px; color:#E25937;">Phone Number : </label></b></td> <td><input type="text" name="phone" style="font-family: tahoma; font-size:25px; color:#E25937;"></td> </tr> <tr> <td><b><label style="font-family: tahoma; font-size:25px; color:#E25937;">WhatsApp Number (Optional) : </label></b></td> <td><input type="text" name="whatsapp" style="font-family: tahoma; font-size:25px; color:#E25937;"></td> </tr> <tr> <td><b><label style="font-family: tahoma; font-size:25px; color:#E25937;">E-mail : </label></b></td> <td><input type="email" name="email" style="font-family: tahoma; font-size:25px; color:#E25937;"></td> </tr> <tr> <td><b><label style="font-family: tahoma; font-size:25px; color:#E25937;">Company Title : </label></b></td> <td><input type="text" name="company" style="font-family: tahoma; font-size:25px; color:#E25937;"></td> </tr> <tr> <td><b><label style="font-family: tahoma; font-size:25px; color:#E25937;">Complaint Title : </label></b></td> <td><input type="text" name="complaintTitle" style="font-family: tahoma; font-size:25px; color:#E25937;"></td> </tr> <tr> <td><b><label style="font-family: tahoma; font-size:25px; color:#E25937;">Details :- : </label></b></td> </tr> </table> <textarea name="details" style="font-family: tahoma; font-size:25px; color:#E25937;" rows="7" cols="56"></textarea> <br><br> <button type="button" id="sendBtn" style="font-family: tahoma; font-size:50px; background-color:#E25937; color:#FFFFFF; width: 200px; height: 74px;">Send</button> </form>
I also changed the button's type to button (so it doesn't submit the form by default) and added IDs to the form and button for easier JS targeting.
Step 2: Read Form Data & Generate .csi File
Next, we'll write JavaScript to grab all user inputs, format them into a .csi file (we can define a simple key-value format for this), and prepare it for email. Add this script right before your closing </body> tag:
document.getElementById('sendBtn').addEventListener('click', async function() { // 1. Grab all form data const form = document.getElementById('complaintForm'); const formData = new FormData(form); // 2. Convert FormData to a string for the .csi file let csiContent = "Complaint Submission\n"; csiContent += "====================\n"; for (const [key, value] of formData.entries()) { if (value.trim()) { // Skip empty optional fields csiContent += `${key.charAt(0).toUpperCase() + key.slice(1)}: ${value}\n`; } } // 3. Create a Blob (file-like object) of the .csi content const csiBlob = new Blob([csiContent], { type: 'text/plain' }); const csiFile = new File([csiBlob], 'complaint.csi', { type: 'text/plain' }); // Now we have the .csi file—next step is sending it via email await sendEmailWithAttachment(csiFile, formData); });
This code listens for the button click, collects all form values, formats them into a readable .csi file, and passes it to an email-sending function we'll write next.
Step 3: Sending the Email (Two Options)
Browsers can't directly send emails with attachments for security reasons, so we have two solid options:
Option 1: Simple Mailto Link (No Backend Needed)
If you don't want to set up a backend, you can use a mailto link to open the user's default email client (Outlook/Gmail) with the complaint content pre-filled. Note: This won't automatically attach the .csi file—users will need to download it first and add it manually.
Modify the sendEmailWithAttachment function like this:
function sendEmailWithAttachment(csiFile, formData) { // Create a download link for the .csi file (so user can save it) const downloadLink = document.createElement('a'); downloadLink.href = URL.createObjectURL(csiFile); downloadLink.download = 'complaint.csi'; downloadLink.click(); // Format the email body const emailBody = Array.from(formData.entries()) .filter(([_, value]) => value.trim()) .map(([key, value]) => `${key.charAt(0).toUpperCase() + key.slice(1)}: ${value}`) .join('\n\n'); // Open default email client const mailtoUrl = `mailto:your-target-email@example.com?subject=New Complaint: ${formData.get('complaintTitle')}&body=${encodeURIComponent(emailBody)}`; window.location.href = mailtoUrl; }
Replace your-target-email@example.com with your actual email address. This is quick to set up but isn't ideal for a professional tool since users have to manually attach the file.
Option 2: Backend-Powered Email (Recommended)
For a seamless experience (auto-attaching the .csi file), you'll need a simple backend. Let's use Node.js with Nodemailer (a popular email library) as an example.
Step 2a: Set Up the Node.js Backend
- First, create a new folder, initialize npm, and install dependencies:
npm init -y npm install express nodemailer cors multer
- Create a file named
server.jswith this code:
const express = require('express'); const nodemailer = require('nodemailer'); const cors = require('cors'); const multer = require('multer'); // For handling file uploads const app = express(); app.use(cors()); app.use(express.json()); // Configure multer to accept file uploads const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); // Configure Nodemailer (use your email provider's SMTP settings) const transporter = nodemailer.createTransport({ service: 'Gmail', // Or 'Outlook' auth: { user: 'your-email@example.com', // Your email pass: 'your-app-password' // Use an app-specific password for Gmail/Outlook } }); // Endpoint to handle email sending app.post('/send-complaint', upload.single('csiFile'), async (req, res) => { try { const { name, phone, whatsapp, email, company, complaintTitle, details } = req.body; const csiFile = req.file; // Email options const mailOptions = { from: email, to: 'your-target-email@example.com', // Your target email subject: `New Complaint: ${complaintTitle}`, text: `Name: ${name}\nPhone: ${phone}\nWhatsApp: ${whatsapp || 'N/A'}\nEmail: ${email}\nCompany: ${company}\n\nComplaint Details:\n${details}`, attachments: [ { filename: csiFile.originalname, content: csiFile.buffer } ] }; // Send the email await transporter.sendMail(mailOptions); res.status(200).send('Complaint sent successfully!'); } catch (error) { console.error(error); res.status(500).send('Failed to send complaint.'); } }); // Start the server const PORT = 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });
Step 2b: Update the Frontend JS to Send Data to the Backend
Replace the sendEmailWithAttachment function in your frontend with this:
async function sendEmailWithAttachment(csiFile, formData) { try { // Create a new FormData object to send to the backend const submitData = new FormData(); submitData.append('csiFile', csiFile); // Add all form fields to the submit data for (const [key, value] of formData.entries()) { submitData.append(key, value); } // Send the data to your backend const response = await fetch('http://localhost:3000/send-complaint', { method: 'POST', body: submitData }); if (response.ok) { alert('Complaint sent successfully!'); document.getElementById('complaintForm').reset(); // Reset the form } else { alert('Failed to send complaint. Please try again later.'); } } catch (error) { console.error(error); alert('An error occurred. Please try again later.'); } }
Make sure to replace your-email@example.com and your-target-email@example.com in the backend code with your actual emails. For Gmail, you'll need to enable app-specific passwords (if 2FA is on) or allow less secure apps (not recommended). For Outlook, use your Outlook email and password.
Final Notes
- The .csi file format is custom, so we used a simple text-based structure—you can adjust the
csiContentformatting to match any specific requirements you have for the file. - For production, make sure to add form validation (check that required fields like name, phone, email, and complaint details are filled) to improve user experience.
内容的提问来源于stack exchange,提问作者user12312714

