如何构建自己的无服务器联系表单?有哪些要求?导航到 handler.js 文件 前端设置 JavaScript 最终输出 为什么选择 Dashbird?DashBird 界面

2025-06-10

如何构建自己的无服务器联系表单

要求是什么?

导航到 handler.js 文件

前端设置

JavaScript

最终输出

为什么选择 Dashbird?

DashBird 界面

静态网站使用 HTML、CSS 和 JavaScript 开发。
您无需设置任何数据库或服务器。GitHub 和 Netlify 为静态网站提供免费托管服务,只需在网站上添加联系表单即可。即使没有用户访问您的网站,您也需要支付服务器费用。使用无服务器 AWS,只有当有人访问您的网页时才会向您收费,如果没有流量,则无需付费。

在本文中,您将了解如何使用 SES(简单电子邮件服务)、Aws Lambda 和无服务器框架构建无服务器联系表单。

电子邮件

要求是什么?

  1. AWS 账户
  2. Node.js
  3. 无服务器框架 cli。
  4. DashBird 账户

让我们构建一个无服务器联系表单

一

首先我们需要安装 Serverless Framework cli。

打开终端并运行以下命令。

npm install -g serverless

sls login // SLS is a shortcut of serverless

Enter fullscreen mode Exit fullscreen mode

2号

sls 登录后,您需要使用无服务器框架配置您的 Aws 凭证。

获取 AWS 凭证

三

在您的电脑中创建一个新目录。

mkdir contactform
cd contactfrom
Enter fullscreen mode Exit fullscreen mode

四

Serverless 为我们提供了不同类型的模板,但我们使用 Nodejs 作为后端,因此我们正在创建 nodejs 模板。

serverless create --template aws-nodejs
Enter fullscreen mode Exit fullscreen mode

上述命令生成样板。

五

现在我们需要初始化Package.json文件并安装一些依赖项。

npm init -y // generates package.json file

npm i -s body-parser cors express serverless-http aws-sdk
Enter fullscreen mode Exit fullscreen mode

现在在您最喜欢的代码编辑器中打开联系表单文件夹。

导航到 handler.js 文件

清除 handler.js 中的所有内容,因为我们是从头开始编写的。

const serverless = require("serverless-http");
const AWS = require("aws-sdk");
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
if (!AWS.config.region) {
AWS.config.update({
region: "add your region" //example us-east-1
});
}
const ses = new AWS.SES();
app.use(cors());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
app.post("/", (req, res) => {
const name = req.body.name;
const email = req.body.email;
const message = req.body.message;
});
module.exports.form = serverless(app);
view raw handler.js hosted with ❤ by GitHub
const serverless = require("serverless-http");
const AWS = require("aws-sdk");
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
if (!AWS.config.region) {
AWS.config.update({
region: "add your region" //example us-east-1
});
}
const ses = new AWS.SES();
app.use(cors());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
app.post("/", (req, res) => {
const name = req.body.name;
const email = req.body.email;
const message = req.body.message;
});
module.exports.form = serverless(app);
view raw handler.js hosted with ❤ by GitHub

我们在第 15 行调用了 SES 构造函数和一个端点。如果您想了解如何使用 Express Checkout 创建无服务器端点,请参阅我的文章《使用无服务器、Express 和 Nodejs 构建和部署 Rest API》

我们需要在post方法中调用ses.sendEmail(params,function(err,data){})方法。

参数

来源 — (字符串)
发送电子邮件的电子邮件地址。此电子邮件地址必须通过 Amazon SES 单独验证。

验证您的电子邮件地址

  1. 打开您的 Aws 控制台并在搜索栏中输入 ses
  2. 点击简单电子邮件服务。
  3. 打开后,在左侧边栏中单击电子邮件地址,添加您的电子邮件地址。
  4. 您将收到一封验证电子邮件。

核实

目的地

此电子邮件的目的地,由收件人、抄送和密送字段组成。

ToAddresses — 电子邮件地址数组。CcAddresses
— 电子邮件地址数组。BccAddresses
— 电子邮件地址数组。

信息:

主题[对象]:
邮件的主题:内容的简短摘要,将出现在收件人的收件箱中。

数据(字符串):表单的内容。

const emailParams = {
Source: "yourname@mail.com", // Your Verified Email
Destination: {
ToAddresses: ["yourname@mail.com"] // Your verfied Email
},
ReplyToAddresses: [req.body.email],
Message: {
Body: {
Text: {
Charset: "UTF-8",
Data: `${message} from ${req.body.email}`
}
},
Subject: {
Charset: "UTF-8",
Data: "You Received a Message from www.domainname.com"
}
}
};
view raw params hosted with ❤ by GitHub
const emailParams = {
Source: "yourname@mail.com", // Your Verified Email
Destination: {
ToAddresses: ["yourname@mail.com"] // Your verfied Email
},
ReplyToAddresses: [req.body.email],
Message: {
Body: {
Text: {
Charset: "UTF-8",
Data: `${message} from ${req.body.email}`
}
},
Subject: {
Charset: "UTF-8",
Data: "You Received a Message from www.domainname.com"
}
}
};
view raw params hosted with ❤ by GitHub

我们需要将这些 params 对象传递给 ses.sendEmail 方法。

更新了 handler.js 文件

const serverless = require("serverless-http");
const AWS = require("aws-sdk");
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
if (!AWS.config.region) {
AWS.config.update({
region: "us-east-1"
});
}
const ses = new AWS.SES();
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post("/", (req, res) => {
const name = req.body.name;
const email = req.body.email;
const message = req.body.message;
const emailParams = {
Source: "yourname@mail.com", // Your Verified Email
Destination: {
ToAddresses: ["yourname@mail.com"] // Your verfied Email
},
ReplyToAddresses: [req.body.email],
Message: {
Body: {
Text: {
Charset: "UTF-8",
Data: `${message} from ${req.body.email}`
}
},
Subject: {
Charset: "UTF-8",
Data: "You Received a Message from www.domainname.com"
}
}
};
ses.sendEmail(emailParams, (err, data) => {
if (err) {
res.status(402).send(`${err} ${err.stack}`);
}
if (data) {
res.send(data);
}
});
});
module.exports.form = serverless(app);
const serverless = require("serverless-http");
const AWS = require("aws-sdk");
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const app = express();
if (!AWS.config.region) {
AWS.config.update({
region: "us-east-1"
});
}
const ses = new AWS.SES();
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post("/", (req, res) => {
const name = req.body.name;
const email = req.body.email;
const message = req.body.message;
const emailParams = {
Source: "yourname@mail.com", // Your Verified Email
Destination: {
ToAddresses: ["yourname@mail.com"] // Your verfied Email
},
ReplyToAddresses: [req.body.email],
Message: {
Body: {
Text: {
Charset: "UTF-8",
Data: `${message} from ${req.body.email}`
}
},
Subject: {
Charset: "UTF-8",
Data: "You Received a Message from www.domainname.com"
}
}
};
ses.sendEmail(emailParams, (err, data) => {
if (err) {
res.status(402).send(`${err} ${err.stack}`);
}
if (data) {
res.send(data);
}
});
});
module.exports.form = serverless(app);

打开您的 serverless.yml 文件并使用以下代码进行更新。

service: contact-form
provider:
name: aws
runtime: nodejs8.10
region: us-east-1
iamRoleStatements:
- Effect: "Allow"
Action:
- "ses:SendEmail"
Resource: "*"
functions:
app:
handler: handler.form
events:
- http: ANY /
- http: 'ANY {proxy+}'
view raw serverless.yml hosted with ❤ by GitHub
service: contact-form
provider:
name: aws
runtime: nodejs8.10
region: us-east-1
iamRoleStatements:
- Effect: "Allow"
Action:
- "ses:SendEmail"
Resource: "*"
functions:
app:
handler: handler.form
events:
- http: ANY /
- http: 'ANY {proxy+}'
view raw serverless.yml hosted with ❤ by GitHub

现在打开终端并运行 sls deploy 命令,即可在 AWS 中部署代码。运行该命令一段时间后,您的 API 端点就会显示在终端中。

终端端点

前端设置

HTML标记

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name= "viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Contact us</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="all">
<form action="" class="items">
<h1>Contact Us</h1>
<div class="error-items">
<p style="color:red" class="error"></p>
</div>
<div>
<label for="name">Name</label>
<input type="text" id="name" required placeholder="Enter Your Name" class="name" />
</div>
<div>
<label for="email">Email</label>
<input type="email" required placeholder="Your Email" id="email" class="normal" />
</div>
<div class="area">
<label for="message" class="area-label">Message</label>
<textarea type="text" placeholder="Message" required id="message" class="txt"></textarea>
</div>
<button>Send</button>
</form>
</div>
<p class="success"></p>
<script src="./script.js"></script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name= "viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Contact us</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="all">
<form action="" class="items">
<h1>Contact Us</h1>
<div class="error-items">
<p style="color:red" class="error"></p>
</div>
<div>
<label for="name">Name</label>
<input type="text" id="name" required placeholder="Enter Your Name" class="name" />
</div>
<div>
<label for="email">Email</label>
<input type="email" required placeholder="Your Email" id="email" class="normal" />
</div>
<div class="area">
<label for="message" class="area-label">Message</label>
<textarea type="text" placeholder="Message" required id="message" class="txt"></textarea>
</div>
<button>Send</button>
</form>
</div>
<p class="success"></p>
<script src="./script.js"></script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub

CSS

*{
box-sizing: border-box;
padding: 0;
margin: 0
}
body{
font-family: sans-serif;
}
.items{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 2rem;
font-size: 1.1rem;
padding: 1rem;
}
input{
padding: 1rem;
margin: .8rem;
width: 25rem;
height: 3rem;
font-size: 1.1rem;
border: 3px solid rgb(31, 121, 255);
outline: none;
}
textarea{
width: 25rem;
height: 10rem;
padding: 1rem;
display: flex;
justify-content: center;
outline: none;
border: 3px solid rgb(31, 121, 255);
font-size: 1.1rem;
}
.area{
display: flex;
}
.area-label{
margin-left:-2rem;
}
.txt{
margin-left:.6rem;
}
button{
padding: 1rem;
width: 10rem;
margin-top: 2rem;
text-align: center;
background-color: rgb(75, 224, 75);
font-size: 1.3rem;
color: rgb(2, 2, 15);
box-shadow: 0 .2rem .2rem black;
}
.success{
background-color: rgb(75, 214, 224);
font-size: 1.2rem;
text-transform: capitalize;
text-align: center;
margin-top: 10rem;
padding: 2rem;
box-shadow: 0 .2rem .2rem rgb(0, 0, 0);
display: none;
}
.error{
display: none;
animation: move .2s ease-in ;
}
@keyframes move{
0%{
opacity: 0;
transform: translateY(-80%);
}
50%{
opacity: .6;
transform: translate(-20%);
}
70%{
opacity: .7;
transform: translate(20%);
}
100%{
opacity: 1;
transform: translate(0);
}
}
view raw style.css hosted with ❤ by GitHub
*{
box-sizing: border-box;
padding: 0;
margin: 0
}
body{
font-family: sans-serif;
}
.items{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 2rem;
font-size: 1.1rem;
padding: 1rem;
}
input{
padding: 1rem;
margin: .8rem;
width: 25rem;
height: 3rem;
font-size: 1.1rem;
border: 3px solid rgb(31, 121, 255);
outline: none;
}
textarea{
width: 25rem;
height: 10rem;
padding: 1rem;
display: flex;
justify-content: center;
outline: none;
border: 3px solid rgb(31, 121, 255);
font-size: 1.1rem;
}
.area{
display: flex;
}
.area-label{
margin-left:-2rem;
}
.txt{
margin-left:.6rem;
}
button{
padding: 1rem;
width: 10rem;
margin-top: 2rem;
text-align: center;
background-color: rgb(75, 224, 75);
font-size: 1.3rem;
color: rgb(2, 2, 15);
box-shadow: 0 .2rem .2rem black;
}
.success{
background-color: rgb(75, 214, 224);
font-size: 1.2rem;
text-transform: capitalize;
text-align: center;
margin-top: 10rem;
padding: 2rem;
box-shadow: 0 .2rem .2rem rgb(0, 0, 0);
display: none;
}
.error{
display: none;
animation: move .2s ease-in ;
}
@keyframes move{
0%{
opacity: 0;
transform: translateY(-80%);
}
50%{
opacity: .6;
transform: translate(-20%);
}
70%{
opacity: .7;
transform: translate(20%);
}
100%{
opacity: 1;
transform: translate(0);
}
}
view raw style.css hosted with ❤ by GitHub

JavaScript

  • 我们需要向端点发出 ajax 请求。
let name = document.querySelector("#name");
let email = document.querySelector("#email");
let message = document.querySelector("#message");
let error = document.querySelector(".error");
let btn = document.querySelector("button");
let success = document.querySelector(".success");
btn.addEventListener("click", submit);
function submit(e) {
e.preventDefault();
var xhr = new XMLHttpRequest();
xhr.open("POST", "yourendpoint", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
}
};
var data = {
name: name.value,
email: email.value,
message: message.value
};
if (name.value && email.value && message.value) {
success.style.display = "block";
success.innerHTML = "Thanks for submitting";
document.querySelector(".all").style.display = "none";
xhr.send(JSON.stringify(data));
} else {
error.style.display = "block";
error.innerHTML = "Please Fill All Details";
}
}
view raw script.js hosted with ❤ by GitHub
let name = document.querySelector("#name");
let email = document.querySelector("#email");
let message = document.querySelector("#message");
let error = document.querySelector(".error");
let btn = document.querySelector("button");
let success = document.querySelector(".success");
btn.addEventListener("click", submit);
function submit(e) {
e.preventDefault();
var xhr = new XMLHttpRequest();
xhr.open("POST", "yourendpoint", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
}
};
var data = {
name: name.value,
email: email.value,
message: message.value
};
if (name.value && email.value && message.value) {
success.style.display = "block";
success.innerHTML = "Thanks for submitting";
document.querySelector(".all").style.display = "none";
xhr.send(JSON.stringify(data));
} else {
error.style.display = "block";
error.innerHTML = "Please Fill All Details";
}
}
view raw script.js hosted with ❤ by GitHub

最终输出

电子邮件

为了监控、调试和检测 lambda 的错误,我们使用Dashbird

为什么选择 Dashbird?

  • Dashbird 帮助我们主动监控健康和错误。

  • Dashbird 的一个主要特点是其用户友好的界面。

  • Dashbird 可视化您的所有 AWS Lambda 指标,如
    内存利用率、调用次数和执行持续时间。

DashBird 界面

Dashbird 监控

希望你们玩得开心,如有任何疑问,请随时询问。

代码库

关于无服务器的其他有趣文章

鏂囩珷鏉ユ簮锛�https://dev.to/sait/how-to-build-your-own-serverless-contact-form---3mkn
PREV
如何在 Angular 中实现延迟加载
NEXT
如何构建你的第一个离线网页?什么是 Service Worker?安装 Event 获取事件