FirebaseFunctions Cors No'Access-Control-Allow-Origin'

时间:2017-10-07 18:52:45

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

我遵循了本教程,但我使用的是nodemailer而不是sendgrid。
https://www.youtube.com/watch?v=wCtNjP9gcqk

我收到此错误

  

对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-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);
  });
});

这就是我在前面所拥有的......我正在使用角度......

    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);
      });

我失去了如何改变或设置火星基地的角色......

非常感谢

---- ---- EDIT

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)

1 个答案:

答案 0 :(得分: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和秘密。 Auth playground step 1

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

如果一切正常,您将被重定向到使用您的Google帐户登录。登录,然后允许访问您的应用,您将再次被重定向到OAuth游乐场并查看令牌选项卡的Exchange授权代码: enter image description here

复制刷新令牌!

然后按如下方式配置您的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)
        });
    });

});

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