【问题标题】:FirebaseFunctions Cors No 'Access-Control-Allow-Origin'FirebaseFunctions Cors 没有“访问控制允许来源”
【发布时间】:2018-03-19 08:02:28
【问题描述】:

我按照本教程进行操作,但我使用的是 nodemailer 而不是 sendgrid。
https://www.youtube.com/watch?v=wCtNjP9gcqk

我收到这个错误

对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'localhost:4200' 不允许访问。响应的 HTTP 状态代码为 500

我在互联网上尝试了几种解决方案..

我发现最符合逻辑的是这个...
https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html

但我不断收到错误

这就是我在服务器端/firebase 上的功能..

const nodemailer = require('nodemailer');
const functions = require('firebase-functions');
const cors = require('cors')({
  origin: true
});


function sendFn(req, res) {
  var transporter = nodemailer.createTransport({
    service: "Gmail",
    auth: {
      user: "user@gmail.com",
      pass: "password"
    }
  });

  var mailOptions = {
    from: '', // sender address (who sends)
    to: '', // list of receivers (who receives)
    subject: '', // Subject line
    replyTo: '',
    text: '', // plaintext body
    html: '' // html body
  };

  mailOptions['from'] = 'Contact';
  mailOptions['to'] = 'address@email.com';
  mailOptions['text'] = req.query.msg;
  mailOptions['replyTo'] = req.query.email;;
  mailOptions['subject'] = "WebContact - " + req.query.name;

  // // send mail with defined transport object   

  return transporter.sendMail(mailOptions).then(() => {
    console.log('Email sent to:');
  }).catch(error => {
    console.error('There was an error while sending the email:', error);
  });
};


exports.httpEmail = functions.https.onRequest((req, res) => {
  var corsFn = cors();
  corsFn(req, res, function() {
    sendFn(req, res);
  });
});

这就是我在前面的内容...我正在使用 angular...

    const url = `firebase.url.function`;
    const params: URLSearchParams = new URLSearchParams();
    const headers = new Headers({ 'Content-Type': 'application/json'. , 'Access-Control-Allow-Origin': '*'});
    const options = new RequestOptions({ headers: headers });

    params.set('name', data['name']);
    params.set('email', data['email']);
    params.set('msg', data['msg']);

    console.log('Enviados' + params);

    this.http.post(url, params, options)
      .toPromise()
      .then(res => {
        console.log(res);
      })
      .catch(err => {
        console.log(err);
      });

我不知道如何在 firebase 端更改或设置 cors ...

非常感谢

----编辑----

Firebase 日志。

TypeError: Cannot read property 'headers' of undefined
at /user_code/node_modules/cors/lib/index.js:219:31
at optionsCallback (/user_code/node_modules/cors/lib/index.js:199:9)
at corsMiddleware (/user_code/node_modules/cors/lib/index.js:204:7)
at exports.httpEmail.functions.https.onRequest (/user_code/index.js:54:18)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/providers/https.js:26:41)
at /var/tmp/worker/worker.js:635:7
at /var/tmp/worker/worker.js:619:9
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)

【问题讨论】:

  • 响应的 HTTP 状态码为 500 ⬅ 这就是你需要解决的问题。您看到有关 Access-Control-Allow-Origin 标头的消息的唯一原因是,与大多数服务器一样,发送该响应的服务器不会将标头添加到 5xx 错误响应中,而只会将它们添加到 2xx 成功响应中.无论如何,那个 500 响应表明一些内部服务器故障。因此,您需要查看服务器端的服务器日志,看看记录了哪些有关导致其发送 500 响应的内部故障的消息。
  • 但是我使用的是firebase函数,还是你的意思是网站服务器??
  • 是的,我的意思是在您的this.http.post(url, params, options) 调用中,无论服务器在url 运行
  • 这是 firebase 函数 url 参数,它是一个云函数,它提供的所有日志都在我所做的新编​​辑中。

标签: node.js typescript firebase google-cloud-functions


【解决方案1】:

我遇到了同样的问题,但在前端部分使用了 React。我通过执行以下步骤设法解决了这个问题:

在导入时设置这些 cors 选项

const cors = require('cors'); const corsOptions = { origin: '*', allowedHeaders: ['Content-Type', 'Authorization', 'Content-Length', 'X-Requested-With', 'Accept'], methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'], optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 };

当您尝试使用 nodemailer 发送邮件并使用您的 Google 凭据(电子邮件、密码)时,Google 将阻止该请求,因为它是可疑的。因此,要使用您的 Gmail 帐户发送邮件,您必须执行以下操作:

现在转到https://developers.google.com/oauthplayground/

点击右侧的设置按钮(小齿轮),并确保在此处填写您的客户 ID 和密码,如屏幕上所示。

完成此操作后,转到选择和授权 API,找到 Gmail API 并对其进行授权。

如果一切正常,您将被重定向到使用您的 Google 帐户登录。登录,然后允许访问您的应用程序,您将再次被重定向到 OAuth 操场并查看 Exchange 授权码以获取令牌选项卡:

复制刷新令牌!

然后像这样配置您的 Nodemailer 传输设置:

const mailTransport = nodemailer.createTransport({
    service: 'Gmail',
    auth: {
        type: 'OAuth2',
        user: 'xxxxxx@gmail.com', // the email you signed on the auth playground
        clientId: 'cliend id here',
        clientSecret: 'client secret here',
        refreshToken: 'refresh token here'
    }
});

这是我的工作云函数:

exports.bookNow = functions.https.onRequest((req, res) => {

    const corsMiddleware = cors(corsOptions);
    corsMiddleware(req, res, () => {
        mailTransport.sendMail({
            from: `blabla@gmail.com`, // sender address
            to: 'blah@gmail.com', // list of receivers
            subject: `You have got a new email!`, // Subject line
            html: `<div>Email body here</div>`
        }).then((info) => {
            res.status(200).send({ message: "Email sent"})
        }).catch(error => {
            res.send(error)
        });
    });

});

这对我有用,我希望对你和其他奋斗的人有用! 祝你好运!

【讨论】:

    猜你喜欢
    • 2016-06-27
    • 1970-01-01
    • 2020-11-26
    • 2018-08-10
    • 2019-02-09
    • 2016-06-02
    • 2020-10-25
    • 2019-09-16
    • 2020-11-02
    相关资源
    最近更新 更多