在当今信息化时代,问卷调查成为了收集用户反馈和意见的重要工具。本文将指导你如何在云服务器上搭建一个简单的问卷调查系统,并使用Bootstrap进行美化。我们将实现创建问卷和参与问卷的功能。
获得服务器
我们将使用云服务器来部署我们的项目。
首先我们打开雨云官网,点击右上角的“登录/注册”,按要求注册一个账号(优惠码记得填pyao
)。
注册好后,我们来到主页的“云服务器”这一栏,选择“购买云服务器”。
参考配置 仅供参考:
区域:中国香港-软银大带宽[四区]
CPU:Xeon® Gold
套餐:流量叠加型-KVM 标配版
操作系统:Ubuntu 22.04 无预装(只要是linux系列都行)
购买好后,我们来到云服务器管理界面,找到你刚才的服务器,它会显示创建中,等变成运行中是,点击服务器卡片的“管理”。
找到这一栏:
然后我们打开SSH工具(Windows 10+ MacOS和Linux有自带的ssh,也可以使用雨云面板的Xtermjs或其他你喜欢的软件),连接上你的服务器。
出现root@RainYun-XXX:~#
就表示连接好了,此时我们输入:
apt update
apt upgrade
reboot
这是用来更新软件的,防止后面出现各种玄学的错误。
reboot
后,SSH连接将显示Connection to XXX.XXX.XXX.XXX Closed
,不要慌,过个3分钟重新连接回去就好了。
安装必要的软件
为了部署,我们还需要在服务器上安装以下软件:
Node.js:用于搭建后端服务
MongoDB:用于存储问卷数据
Nginx:用于反向代理和静态文件服务
apt update
apt upgrade
curl -sL https://deb.nodesource.com/setup_18.x | bash -
apt install -y nodejs
apt install -y nginx
apt install -y mongodb
systemctl start mongodb
systemctl enable mongodb
(安装剪影)
有warning
不用管,只要能安装就好了。
出现这几行 五彩斑斓 的文字,就表示NodeJS安装好了!
开始搭建
项目初始化
创建一个新的Node.js项目:
mkdir survey_sys
cd survey_sys
npm init -y
安装 Node.js 所需的依赖:
npm install express
npm install mongoose
npm install body-parser
npm install cors
编写后端代码
在项目根目录下创建一个server.js文件,这个是用来创建服务器的,和WebMC
项目的server.js
类似,都是为了创建一个能简单发送/接受响应的服务端。
其中app.post(...)
和Flask,Django等@route
相似,表示一个页面。
同时,这个程序还会监听3000端口,这就意味我们可以用你的服务器IP:3000
来访问你的界面。
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
const PORT = process.env.PORT || 3000;
mongoose.connect("mongodb://localhost:27017/surveydb",{ useNewUrlParser: true, useUnifiedTopology: true });
const surveySchema = new mongoose.Schema({
title: String,
questions: [String],
responses: [[String]]
});
const Survey = mongoose.model("Survey", SurveySchema);
app.use(cors());
app.use(bodyParser.json());
app.post("/surveys",async (req,res) => {
const survey = new Survey(req.body);
await survey.save();
res.status(201).send(survey);
});
app.get("/surveys",async (req,res) => {
const surveys = await Survey.find();
res.send(surveys);
});
app.post("/surveys/:id/responses",async (req,res) => {
const survey = await Survey.findById(req.params.id);
survey.responses.push(req.body.responses);
await survey.save();
res.status(201).send(survey);
});
app.listen(PORT, () => {
console.log("服务器已启动,访问http://你的服务器IP:3000");
});
启动服务端
在终端中运行以下命令启动服务:
node server.js
出现服务器已启动,访问http://你的服务器IP:3000
,就表示服务器已经在监听这个端口了。
搭建前端
编写index.html代码
index.html
就是整个项目的核心界面了,提供了各个界面的导航。
我们加上了boostrap 3
来优化界面,显得非常Pro
,可以参考菜鸟教程 有关bootstrap的介绍
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>问卷调查系统 - Powered by Node.JS</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.js">
<style>
body {
background-color: #ccc;
}
</style>
</head>
<body>
<div class="container">
<h1 class="mt-5">问卷调查系统</h1>
<form id="survey-form">
<h2 class="mt-4">创建问卷</h2>
<div class="form-group">
<label for="title">问卷标题</label>
<input type="text" class="form-control" id="title" required>
</div>
<div class="form-group">
<label for="questions">输入问题(格式为:使用半角逗号分隔)</label>
<input type="text" class="form-control" id="questions" required>
</div>
<button type="submit" class="btn btn-primary">提交问卷</button>
</form>
<h2 class="mt-4">参与问卷</h2>
<div id="surveys"></div>
</div>
<script>
document.getElementById("survey-form").addEventListener("submit", async (e) => {
e.preventDefault();
const title = document.getElementById("title").value;
const questions = document.getElementById("questions").value.split(",");
const response = await fetch("http://localhost:3000/surveys", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title, questions })
});
if (response.ok) {
alert("问卷创建成功!");
document.getElementById("survey-form").reset();
loadSurveys();
}
});
async function loadSurveys() {
const response = await fetch("http://localhost:3000/surveys");
const surveys = await response.json();
const surveysDiv = document.getElementById("surveys");
surveysDiv.innerHTML = "";
surveys.forEach(survey => {
const surveyElement = document.createElement("div");
surveyElement.className = "card mt-2";
surveyElement.innerHTML = `
<div class="card-body">
<h5 class="card-title">${survey.title}</h5>
<p class="card-text">${survey.questions.join(", ")}</p>
<button class="btn btn-secondary" onclick="participateSurvey("${survey._id}")">参与问卷</button>
</div>
`;
surveysDiv.appendChild(surveyElement);
});
}
async function participateSurvey(surveyId) {
const responses = prompt("请输入你的答案(格式为:使用半角逗号分隔)");
if (responses) {
await fetch(`http://localhost:3000/surveys/${surveyId}/responses`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ responses: responses.split(",") })
});
window.location.href = "/thank_participate.html";
}
}
window.onload = loadSurveys;
// 不要写loadSurveys()
</script>
</body>
</html>
4. 配置Nginx
到此,我们可以同个你的服务器IP:3000
来访问这个问卷了!
但为了能让用户通过80
端口访问(不用加入:3000
),我们可以使用nano
or vim
打开/etc/nginx/sites-available/default
添加以下内容:
server {
listen 80;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /public {
alias /你的SurveySys路径/public;
}
}
重启Nginx
重启以应用更改:
systemctl restart nginx
更多功能
你可以加上更多功能,不过要多亏了Node.JS。
比如用户系统(再创建一个数据库?),防注入,防刷提交量(IP检测)等功能。
[sub plz]