【问题标题】:Nuxt.js: Contact form submissionNuxt.js:联系表单提交
【发布时间】:2021-09-28 12:24:50
【问题描述】:

我正在使用服务器中间件来处理来自联系表单的 POST。

问题是,我创建的中间件文件似乎没有运行。我使用 VS Code 添加了断点,它们不会在 contact.js 中触发,但它们会在 contact.vue 中触发(在 VS Code 中,我确保在适当的客户端/服务器端环境中添加断点)。甚至我在contact.js 中的控制台日志信息也没有出现。好像文件丢失了。

发生的情况是发出 POST 调用并保持打开状态,但没有响应。 POST 的属性和值都在那里。

我怀疑 createTransport({sendmail: true}) 失败,因为我的开发系统上没有 sendmail,但没有抛出错误。

你能看看我有什么遗漏吗?我想做的只是在提交表单时发送一封电子邮件,但这似乎很难!

我被https://blog.lichter.io/posts/emails-through-nuxtjs/指导

所有软件包都已安装。

我就是这样设置的...

nuxt.config.js

export default {
.
.
.
  serverMiddleware: [
    '~/api/contact'
  ],
.
.
.
}

pages/contact.vue

<template>
.
.
.
            <form class="form-email row mx-0"
              data-success="Thanks for your enquiry, we'll be in touch shortly."
              data-error="Please fill in all fields correctly."
              @submit.prevent="submitForm">
              <div class="col-md-6 col-12 text-xl"> <label>Your Name:</label> <input v-model="name" type="text" name="name"
                  class="validate-required"> </div>
              <div class="col-md-6 col-12 text-xl"> <label>Email Address:</label> <input v-model="email" type="email" name="email"
                  class="validate-required validate-email"> </div>
              <div class="col-md-12 col-12 text-xl"> <label>Message:</label> <textarea v-model="message" rows="4" name="message"
                  class="validate-required"></textarea> </div>
              <div class="col-md-5 col-lg-4 col-6"> <button type="submit" class="btn btn--primary type--uppercase">Submit</button> </div>
            </form>
.
.
.
</template>

<script>
  export default {
    data () {
      return {
        name: '',
        email: '',
        message: ''
      }
    },

    mounted() {
      mr.documentReady($);
      mr.windowLoad($);
    },

    methods: {
      async submitForm () {
        try {
          await this.$axios.$post('', {
            name: this.name,
            email: this.email,
            msg: this.message
          });
          await new Promise(resolve => setTimeout(resolve, 2500));
        } catch (e) {
          console.error(e);
        }
      }
    }
  }
</script>

api/contact.js

const express = require('express')
const nodemailer = require('nodemailer')
const validator = require('validator')
const xssFilters = require('xss-filters')

const app = express()

app.use(express.json())

app.get('/', function (req, res) {
  res.status(405).json({ error: 'sorry!' })
})

app.post('/', function (req, res) {
  const attributes = ['name', 'email', 'message'] // Our three form fields, all required

  // Map each attribute name to the validated and sanitized equivalent (false if validation failed)
  const sanitizedAttributes = attributes.map(n => validateAndSanitize(n, req.body[n]))

  // True if some of the attributes new values are false -> validation failed
  const someInvalid = sanitizedAttributes.some(r => !r)

  if (someInvalid) {
    // Throw a 422 with a neat error message if validation failed
    return res.status(422).json({ 'error': 'Ugh.. That looks unprocessable!' })
  }

  sendMail(...sanitizedAttributes)
  res.status(200).json({ 'message': 'OH YEAH' })
})

module.exports = {
  path: '/api/contact',
  handler: app
}

const validateAndSanitize = (key, value) => {
  const rejectFunctions = {
    name: v => v.length < 4,
    email: v => !validator.isEmail(v),
    message: v => v.length < 25
  }

  // If object has key and function returns false, return sanitized input. Else, return false
  return rejectFunctions.hasOwnProperty(key) && !rejectFunctions[key](value) && xssFilters.inHTMLData(value)
}

const sendMail = (name, email, message) => {
  console.info('Info: ????'
        +'\n Contact page submission.'
        +'\n Date: '+ new Date().toLocaleTimeString() +' '+ new Date().toLocaleDateString()
        +'\n Name: '+ name
        +'\n Email: '+ email
        +'\n Message: '
        +'\n'
        +'\n'+ message
        +'\n'
        +'\n End of submission.'
        +'\n');
  let transporter = nodemailer.createTransport({
    sendmail: true,
    newline: 'unix',
    path: '/usr/sbin/sendmail'
  })
  transporter.sendMail({
    from: email,
    to: 'mail@foobar.com',
    subject: 'Foo Bar: Contact Form',
    text: message
  }, (err, info) => {
    console.log(info.envelope);
    console.log(info.messageId);
  })
}

【问题讨论】:

标签: javascript node.js vue.js vuejs2 nuxt.js


【解决方案1】:

我最近发布了一个Nuxt.js module,它允许通过路由和注入变量发送电子邮件。你可以这样使用它:

$ npm install nuxt-mail @nuxtjs/axios

在您的nuxt.config.js 文件中:

export default {
  modules: [
    '@nuxtjs/axios',
    ['nuxt-mail', {
      smtp: {
        host: "smtp.example.com",
        port: 587,
      },
    }],
  ],
}

在你的组件中使用它:

this.$mail.send({
  from: 'John Doe',
  subject: 'Incredible',
  text: 'This is an incredible test message',
  to: 'johndoe@gmail.com',
})

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • @desertnaut 喜欢这个?
  • 是的,及时 - 帖子已经有 4 票建议删除。下次请记住,仅链接的答案有资格被删除。
  • @desertnaut 哦,好的,感谢您的提示和保留帖子!我没有收到关于第一条评论的电子邮件通知,这就是我迟到的原因。
  • 我正在配置 Sendinblue SMTP,但我收到了 405 响应。知道如何使它工作吗?
【解决方案2】:

您的不起作用,因为您没有调用正确的路径,在您的serverMiddleware 中您说/api/contact 指向contact.js 文件。

这意味着/api/contact 等于contact.js 的路由,因此,您应该调用:

this.$axios.post('/api/contact')

【讨论】:

  • 从那个角度看你可能是对的,因为我一直在改变路径,认为它不正确。但在与@manniL 通话时,他指出这是因为我已将环境设置为在 0.0.0.0 上运行,并且我应该将 axios 配置为在相同的 IP 地址上加载,因此它找不到脚本。
【解决方案3】:

@manniL 在电话中向我指出,在我的nuxt.config.js 中,我已将环境设置为在 0.0.0.0 上加载,以便我可以从另一台机器访问它。

export default {
  server: {
    port: 3000,
    host: '0.0.0.0' // default: localhost
  },
  ...
}

我还需要使用相同的 IP 地址设置 axios 配置,这就是它找不到 api/contact.js 的原因。


抱歉,我应该在问题中发布完整的nuxt.config.js,因为它与默认设置不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多