如何在使用 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 并在设置标头后发送204res.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 函数时,如何检索已更新的记录?

使用 Firebase 可调用函数时如何检索用户的身份验证数据?

更正函数,不称为运行时

如何更正EXCEL中的#NUM!错误

如何更正括号的添加以不必要地使用括号python3

如何在 Flutter 中使用 Firebase Messaging ^8.0.0-dev.8 收到通知时运行函数?