如何使用Lambda函数将nodemailer连接到Vue.js和Netlify应用程序

问题描述 投票:-1回答:1

我在Netlify上有一个使用Vue.js构建的静态网站,我特别需要捕获从联系路径发送的x-www-form-urlencoded数据。

因为它是一个spa和动态呈现的表单,我在index.html中添加了这个(预渲染并允许Netlify在加载时看到表单)

public/index.htmlsrc/views/Contact.vue

<form 
  netlify-honeypot="bot-field"
  name="contact"
  data-netlify="true" hidden>

    <input name="bot-field" />
    <input type="text" name="name" />
    <input type="email" name="email" />
    <input type="text" name="subject" />
    <textarea rows="5" name="message"></textarea>

</form>

联系人视图:

<form
  netlify-honeypot="bot-field"
  name="contact" method="post"
  data-netlify="true"
  @submit.prevent="handleSubmit">

  <input type="hidden" name="form-name" value="contact" />
    <p style="opacity: 0;">
      <label>Don’t fill this out if you're human: <input name="bot-field" /></label>
    </p>
    <p>
      <label>Your Name: <input v-model="form.name" type="text" name="name" /></label>
    </p>
    <p>
      <label>Your Email: <input v-model="form.email" type="email" name="email" /></label>
    </p>
    <p>
      <label>Your Subject: <input v-model="form.subject" type="text" name="subject" /></label>
    </p>
    <p>
      <label>Message: <textarea v-model="form.message" rows="5" name="message"></textarea></label>
    </p>
    <p>
      <button>Send</button>
    </p>

</form>

组件中的数据属性是建模的,POST数据的方法如下:

export default {
  name: 'contact',
  data: () => ({
    form: {
      name: '',
      email: '',
      subject: '',
      message: '',
    },
  }),
  methods: {
    encode (data) {
      return Object.keys(data)
        .map(
          key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`,
        )
        .join('&');
    },
    handleSubmit () {
      const axiosConfig = {
        header: { 'Content-Type': 'application/x-www-form-urlencoded' },
      };
      axios.post(
        '/',
        this.encode({
          'form-name': 'contact',
          ...this.form,
        }),
        axiosConfig,
      )
        .then(() => console.log('success'))
        .catch(e => console.error(e));
    },
  },
};

系统的下一部分是由Netlify运行的lambda函数。每次应用程序收到表单提交时,Netlify都允许使用submission-created函数。您所要做的就是在项目的根目录中创建一个目录,其中包含submission-created.js文件。此目录需要在netlify.toml中指定,因此Netlify知道在哪里查找您的功能。

另一个警告是,如果您的函数需要依赖项,则需要压缩包含node_modules的文件夹。我在package.json中使用bestzip依赖项自动执行此操作。

package.json

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "zip": "cd functions/submission-created && bestzip ../../functions-build/submission-created.zip *",
    "clean": "rm -rf functions-build && mkdir functions-build",
    "prebuild": "npm run clean && npm run zip"
}

正如您所看到的,我处理这个的方法是在functions/submission-created/submission-created.js中编写函数的源代码我还有一个functions-build目录,它是netlify.toml中指定的目录,它将包含压缩的提交创建文件夹。

基本上,我npm init -y函数/ submission-created目录和npm install nodemailer,当prebuid运行时,它删除当前函数-build并重新创建它,然后将函数压缩到具有它依赖项的目录中。

这是netlify.toml

[build]
  functions = "./functions-build"

最后,重要代码所在的位置是submission-created.js文件:


exports.handler = function(event, context, callback) {
  const nodemailer = require('nodemailer');
  const querystring = require('querystring');
  const payload = querystring.parse(event.body);
  const { name, email, subject, message } = payload;

  // create reusable transporter object using the default SMTP transport
  let transporter = nodemailer.createTransport({
    host: "xxx",
    port: 587,
    secure: false, // true for 465, false for other ports
    auth: {
      user: 'xxx', // generated ethereal user
      pass: 'xxx' // generated ethereal password
    },
    tls: {
      rejectUnauthorized: false,
    },
  });

  // setup email data with unicode symbols
  let mailOptions = {
    from: `"website enquiry 👻" <${email}>`, // sender address
    to: "[email protected], [email protected]", // list of receivers
    subject: `${subject} ✔`, // Subject line
    text: `name: ${name}, \n email: ${email}, \n message: ${message}\n`, // plain text body
  };

  // send mail with defined transport object
  transporter.sendMail(mailOptions)
  .then(() => {
    callback(null, { statusCode: 200, body: 'Success' });
  })
  .catch(e => callback(e, { statusCode: 500, body: 'Error sending email' }));

};

主要问题

表格记录在Netlify的提交中。问题在于功能:

在开发中(使用netlify-lambda在本地托管lambda函数)我收到在网站上输入的属性。

在生产中,属性是不确定的。并且完整的事件对象不会在函数中记录到控制台。

javascript vue.js lambda nodemailer netlify
1个回答
2
投票

答案在于生产与开发中的事件参数。

修复:

// How to get post parameters in production
exports.handler = function(event, context, callback) {
  const payload = JSON.parse(event.body).payload;
  const { name, email, subject, message } = payload;
}
© www.soinside.com 2019 - 2024. All rights reserved.