如何在使用 Firebase 函数时更正“请求的资源上不存在‘Access-Control-Allow-Origin’标头”错误?
Posted
技术标签:
【中文标题】如何在使用 Firebase 函数时更正“请求的资源上不存在‘Access-Control-Allow-Origin’标头”错误?【英文标题】:How do i correct "No 'Access-Control-Allow-Origin' header is present on the requested resource" error in express with Firebase functions? 【发布时间】:2021-03-04 18:45:10 【问题描述】:我正在尝试通过具有 Firebase 功能的 nodemailer 发送邮件。邮件的数据将从表单中提供,但我收到此错误
CORS 策略已阻止从源“my-angular-web-app”访问“my-firebase-functions”处的 XMLHttpRequest:请求的资源上不存在“Access-Control-Allow-Origin”标头。
这是我的 Firebase 函数
app.use((req, res, next) =>
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'https://stanleyogbonna-5228d.web.app');
res.setHeader('Access-Control-Allow-Origin', 'https://stanleyogbonna-5228d.firebaseapp.com');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,Content-Type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
);
//to make it work you need gmail account
const gmailEmail = functions.config().gmail.login;
const gmailPassword = functions.config().gmail.pass;
admin.initializeApp();
app.post('/visitor/contact', (req, res, next) =>
//transporter is a way to send your emails
const transporter = nodemailer.createTransport(
service: 'gmail',
auth:
user: gmailEmail,
pass: gmailPassword
);
const mailOptions =
from: gmailEmail,
to: req.body.email,
subject: 'Full stack developer',
html: `<h1 style="color:blue;">Welcome $req.body.firstName</h1>
<p style="font-size:25px;">Thank you very much for contacting me. i hope you are
having a great time where ever you may be.</p>
<p style="font-size:25px;">I am a full stack developer by training and i am available at the moment for a MEAN stack job That will challenge me to be better.</p>
<p style="font-size:23px;">Thanks $req.body.firstName</p>`
;
transporter.sendMail(mailOptions);
)
// catch 404 and forward to error handler
app.use((req, res, next) =>
next(createError(404));
);
// error handler
app.use((err, req, res, next) =>
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : ;
// render the error page
res.status(err.status || 500);
res.render('error');
);
exports.app = functions.https.onRequest(app);
【问题讨论】:
如果你使用 cors 中间件来处理这个问题可能会更容易。 expressjs.com/en/resources/middleware/cors.html 在您的 cors 中间件中,检查请求方法OPTIONS
并在设置标头后发送204
和res.sendStatus(204)
。浏览器发送一个 OPTIONS 请求来检查 cors。
【参考方案1】:
您应该使用 cors
包来解决 CORS 问题。
请在您的节点中设置cors
。
我可以向您展示我使用cors
发送邮件的firebase 云功能。
顺便说一下,我使用了sendgrid
而不是node mailer
。
我将通过展示我的代码来展示你应该如何实现 cors
包装你的函数,因为我通常使用这种方式将我的函数与 cors
打包。
exports.sendEmail = functions.https.onRequest((req, res) =>
if (!req.body) return res.sendStatus(400);
return cors(req, res, () =>
var to = req.body.to;
var from = req.body.from;
var sender_name = req.body.sender_name;
var message = req.body.message;
var pkgname = req.body.pkgname;
var html = "<h2>" + sender_name + "</h2>" + message;
const sgMail = require("@sendgrid/mail");
const subject = "Pre registration - " + pkgname + " - " + sender_name;
sgMail.setApiKey(
"sendgrid api key"
);
const msg =
to: to,
from: from,
subject: subject,
html: html,
;
sgMail.send(msg, (sendError, sendRes) =>
if (sendError) return res.status(500).send(sendError);
else return res.status(200)(sendRes);
);
);
);
仅供参考sendgrid
是免费的!
【讨论】:
以上是关于如何在使用 Firebase 函数时更正“请求的资源上不存在‘Access-Control-Allow-Origin’标头”错误?的主要内容,如果未能解决你的问题,请参考以下文章
在 Firebase 中使用 onUpdate 函数时,如何检索已更新的记录?