I am working on a website(MERN) which has a newsletter as well as a contact form both of my forms are sent on different routes, '/subscribe' and '/contact' respectively. I have hosted the server and client side on different domains. The contact form is working perfectly but in subscribe form I am facing a CORS error which says request denied by the server.
The specific error is "official-site-version-2-0-8tjp.vercel.app/:1 Access to fetch at 'https://official-site-version-2-0.vercel.app/subscribe' from origin 'https://official-site-version-2-0-8tjp.vercel.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
My server side code is
// Allow requests from your frontend domain
const corsOptions = {
origin: ["https://official-site-version-2-0-8tjp.vercel.app","https://official-site-version-2-0.vercel.app"],
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
};
app.use(cors(corsOptions));
app.use(express.json());
app.listen(5000, () => console.log("Server Running"));
console.log(process.env.EMAIL_USER);
console.log(process.env.EMAIL_PASS);
const contactEmail = nodemailer.createTransport({
service: 'gmail',
auth: {
user: <email>,
pass: <password>
},
});
contactEmail.verify((error) => {
if (error) {
console.log(error);
} else {
console.log("Ready to Send");
}
});
// Endpoint handler for handling contact form submissions
app.post("/contact", (req, res) => {
const name = req.body.firstName + req.body.lastName;
const email = req.body.email;
const message = req.body.message;
const phone = req.body.phone;
const mail = {
from: name,
to: "[email protected]",
subject: "Contact Form Submission - Portfolio Devlooper",
html: `<p>Name: ${name}</p>
<p>Email: ${email}</p>
<p>Phone: ${phone}</p>
<p>Message: ${message}</p>`,
};
contactEmail.sendMail(mail, (error) => {
if (error) {
res.json(error);
} else {
res.json({ code: 200, status: "Message Sent" });
}
});
});
app.post("/subscribe", async (req, res) => {
try {
if (!req.body.email) {
return res.status(400).json({ error: 'Email is required' });
}
const db = client.db(dbName);
const emailsCollection = db.collection('emails');
const result = await emailsCollection.insertOne({ email: req.body.email });
console.log('Email saved:', req.body.email);
res.status(201).json({ message: 'Subscription successful', insertedId: result.insertedId });
} catch (error) {
console.error('Error subscribing:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
app.get('/', (req, res) => {
res.send('Server is running! Click <a href="https://official-site-version-2-0-8tjp.vercel.app">here</a>');
});
And my Client side code is
const handleSubmit = async (e) => {
e.preventDefault();
if (!email || email.indexOf('@') === -1) {
return;
}
try {
const response = await fetch('https://official-site-version-2-0.vercel.app/subscribe', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
});
const data = await response.json();
// Handle response
if (response.ok) {
// If subscription is successful, call onValidated with success status
onValidated('success', data.message);
// Clear email field after successful subscription
setEmail('');
} else {
// If subscription fails, call onValidated with error status
onValidated('error', data.message);
}
} catch (error) {
console.error('Error:', error);
// Handle network errors
onValidated('error', 'Network error. Please try again later.');
}
};