Node.js使用nodemailer报错transporter.sendMail is not a function如何解决
问题根因
你报transporter.sendMail is not a function错误的核心原因是server.js中变量作用域和代码位置逻辑错误,一共3个核心问题:
- 文件顶部初始化的全局
transporter = '#'是字符串类型,本身不存在sendMail方法 - 在
app.post('/mail')的回调函数内部用let重新定义的局部transporter,只在回调函数内部生效,外部访问不到 mailOptions定义、transporter.sendMail调用都写在了app.post路由的外面,服务器启动时就会直接执行这部分代码,不会等到用户提交表单请求时触发,也拿不到用户提交的表单数据
另外你的前端app.js里fetch的语法也有错误,then方法写在了fetch的配置对象内部,会导致请求异常。
修复后的server.js代码
const express = require('express'); const path = require('path'); const nodemailer = require('nodemailer'); const dotenv = require('dotenv'); dotenv.config(); let initialPath = path.join(__dirname, "public"); let app = express(); app.use(express.static(initialPath)); app.use(express.json()); app.get('/', (req, res) => { res.sendFile(path.join(initialPath, "index.html")); }) app.post('/mail', (req, res) => { const { firstname, lastname, email, msg } = req.body; // 把transporter定义、mailOptions、sendMail都挪到路由回调内部 let transporter = nodemailer.createTransport({ service: 'gmail', auth: { user: process.env.EMAIL, pass: process.env.PASSWORD } }) const mailOptions = { from: 'yyy@gmail.com', to: 'xxx@gmail.com', subject: 'Portfolio', text: `First name: ${firstname}, \nLast name: ${lastname}, \nEmail: ${email}, \nMessage: ${msg}` } transporter.sendMail(mailOptions, (err, result) => { if (err){ console.log(err) res.json('Oops error occurred') } else{ res.json('thanks for emailing me'); } }) }) app.listen('3000', () => { console.log('listening....'); })
修复后的app.js代码
const links = document.querySelectorAll('.link'); links.forEach(link => { link.addEventListener('click', () =>{ links.forEach(ele => ele.classList.remove('active')); link.classList.add('active'); }) }) // contact form const contactBtn = document.querySelector('.contact-btn'); const firstName = document.querySelector('.first-name'); const lastName = document.querySelector('.last-name'); const email = document.querySelector('.email'); const msg = document.querySelector('.message'); contactBtn.addEventListener('click', () => { if(firstName.value.length && lastName.value.length && email.value.length && msg.value.length ){ // 修复fetch的then位置错误 fetch('/mail', { method: 'post', headers: new Headers({'Content-Type': 'application/json'}), body: JSON.stringify({ firstname: firstName.value, lastname: lastName.value, email: email.value, msg: msg.value, }) }) .then(res => res.json()) .then(data => { alert(data); }) } })
额外注意事项
如果使用Gmail发信,直接填账号密码会被拦截,需要先开启Google账号的两步验证,然后生成应用专用密码,填到process.env.PASSWORD对应的.env文件里才能正常发信。
内容的提问来源于stack exchange,提问作者IT_TE_42_Naman pandey
相关产品推荐
相关产品推荐

