本项目需独自完成前后端全栈任务,实现前端向后端请求数据,deepseek辅助搜索所需要的数据,前端拿到后进行展示。
一.创建两个文件夹,client(存储前端文件),server(存储后端文件)
二.搭建前端页面
- 在目录(client)下创建符合 Web 标准的 index.html 文件,构建具备完整语义化结构的前端主页面
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<h1>用户列表</h1>
<div class="search-container">
<input type="text" id="nameSerch" placeholder="按名字搜索">
<button>搜索</button>
</div>
<table id="userTable">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>地址</th>
</tr>
</thead>
<tbody id="userTbody">
</tbody>
</table>
<script src="./index.js"></script>//引入index.js文件
</body>
</html>
别忘记引入index.js文件
- 在目录(client)下创建模块化的 style.css 样式表文件,基于 CSS 最佳实践实现页面样式渲染与视觉交互效果
style.css
body{
margin: 20px;
}
.search-container{
margin-bottom: 20px;
}
#userTable{
width: 60%;
border-collapse: collapse;
}
th,td{
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th{
background-color: #f2f2f2;
}
#nameSerch{
padding: 6px;
margin-right: 10px;
}
button{
padding: 6px 12px;
cursor: pointer;
/* 把鼠标放到按钮上时变成一只手 */
background-color: #4caf50;
border: none;
color: white;
}
三.创建index.js文件实现对后端数据的请求和数据的接收
- 调用window.onload事件实现页面初次加载后,将获取的用户信息展示到页面上
js
window.onload = function(){}
- 创建fetchUsers()函数向后端发送请求,获取用户信息
-
- 使用fetch()API发送HTTP请求,通过后端提供的接口获取用户信息
js
async function fetchUsers(){ //获取用户信息
//向后端发送请求获取用户信息
const res=await fetch(`http://localhost:3003/api/users`)
}
四.进行后端代码的编写
1.打开server文件夹的集成终端,输入npm init -y命令,进行目录的初始化,以便于等会下载使用第三方插件
2.由于本项目不使用数据库,则自己创建一个db.json文件进行存储数据,如:
db.json
{
"users": [
{
"id": 1,
"name" :"板",
"age" :18,
"address":"南昌"
},
{
"id": 2,
"name" :"猪",
"age" :19,
"address":"南京"
},
{
"id": 3,
"name" :"老",
"age" :30,
"address":"北京"
},
{
"id": 4,
"name" :"小牛",
"age" :50,
"address":"上海"
},
{
"id": 5,
"name" :"小虎",
"age" :20,
"address":"西安"
}
]
}
3.创建server.js文件完成以下三个任务
- 创建一个服务
引入node自带的http模块,用于创建服务
js
const http = require('http');
const server =http.createServer((req,res)=>{ }
server.listen(3003,()=>{ //监听一个3003端口
console.log('服务启动成功');
})
- 定义一个接口 地址为/api/users
js
const server =http.createServer((req,res)=>{
if(req.url.includes('/api/users')){}
}//'/api/users'就是一个接口
//req为前端传过来的请求体,包含前端传过来的所有内容
运行后端代码的一个小工具,实现每次修改好代码后,会自动重启
1.输入npx nodemon server.js命令在线使用nodemon
2.输入npm i nodemon g命令全局本地下载nodemon,后使用nodemon server.js命令进行运行即可
- 读取 db.json文件,向前端返回数据
1.引入node封装的fs模块,实现文件的增删改查等有关文件的任务
js
const fs = require('fs');
2.读取数据并返回给前端(代码有注释)
js
const data =fs.readFileSync('./db.json','utf-8')//utf-8表示要读取文件的编码方式
const users =JSON.parse(data).users //上一步读取到的数据只是一份字符串,这一步就是将他们转换成对象,.user表示读到了users[]这个数组
res.end(JSON.stringify({
success:true,//是一个状态标识,表示操作成功
data:users//将用户数据包含在响应中
}))
//JSON.stringify是将对象转成字符串,res.end是将数据传给前端
3.处理跨域问题
js
res.setHeader('Access-Control-Allow-Origin','*')
res.setHeader('Access-Control-Allow-Headers','*')
res.setHeader('Access-Control-Allow-Methods','*')
五.回到前端接收数据
- 解析并接收JSON数据
js
window.onload =async function(){
const users =await fetchUsers()//获得到的用户信息
}
async function fetchUsers(){
const res=await fetch(`http://localhost:3003/api/users`)
const users =await res.json() //解析返回的JSON数据
return users.data //返回用户信息
}
- 创建一个renderUsers函数实现将从后端接收的数据展示在页面上
js
window.onload =async function(){
const users =await fetchUsers()//获得到的用户信息
renderUsers(users)
}
function renderUsers(user){ //渲染用户信息
const tbody =document.querySelector('tbody') //获取tbody标签
for (let i =0;i< user.length;i++){
const tr=document.createElement('tr')//创建一个tr标签
tr.innerHTML=`
<td>${user[i].id}</td>
<td>${user[i].name}</td>
<td>${user[i].age}</td>
<td>${user[i].address}</td>
`
tbody.appendChild(tr)//把tr塞到tbody里面
}
}

六.实现页面按姓名搜索后,单独展示结果
- 前端发送请求
-
- 给搜索按钮添加点击事件
-
- 获取输入框的值
-
- 向后端发送请求,将输入框的值作为参数传递给后端,获取想要的用户数据
js
const btn =document.querySelector('.search-container button')//获取搜索按钮
const input = document.querySelector('#nameSerch')//获取input框
btn.addEventListener('click',async()=>{
//获取输入框的值
//向后端发送请求,将输入框的值作为参数传递给后端
const users =await fetchUsers(input.value)
})
-
- 同样调用fetchUsers()函数(要稍作修改,添加一个name参数,并修改接口地址)
js
async function fetchUsers(name){
const res=await fetch(`http://localhost:3003/api/users/?name=${name}`)
const users =await res.json()
return users.data
}
- 后端对请求的处理
-
- 获取完整的地址
-
- 获取前端传过来的name参数
在server文件夹下输入npm i openai命令安装openai插件
-
- 引入openai
js
const { OpenAI } = require('openai');//引入openai
-
- 在server文件夹中创建一个.evn文件用于存放你自己的DEEPSEEK_API_KEY
在server文件中装一个dotenv插件 命令:npm i dotenv用于读取.evn文件中的数据
-
- 引入dotenv插件并调用
js
require('dotenv').config()//调用dotenv插件
-
- 使用deepseek自动帮我们在db.json文件中找到所需数据
-
- 将数据返回给前端
js
if(req.url.includes('/api/users')){ //'/api/users'就是一个接口
const url =new URL(req.url,`http://${req.headers.host}`)//得到一个完整地址
const query = url.searchParams.get('name') //获取到了前端传过来的name参数
if(req.url.includes('/api/users')){ //'/api/users'就是一个接口
const url =new URL(req.url,`http://${req.headers.host}`)//得到一个完整地址
const query = url.searchParams.get('name') //获取到了前端传过来的name参数
if(query == 'all'){//如果前端传过来的参数是all则返回所有的数据
const data =fs.readFileSync('./db.json','utf-8')//utf-8表示要读取文件的编码方式
const users =JSON.parse(data).users //上一步读取到的数据只是一份字符串
//这一步就是将他们转换成对象,.user表示读到了users[]这个数组
res.end(JSON.stringify({
success:true,
data:users
})) //JSON.stringify是将对象转成字符串,res.end是将数据传给前端
}else{
const data =fs.readFileSync('./db.json','utf-8')
const users=await openai.chat.completions.create({
messages: [
{ role: "system", content: "你是一个很好的助手" },
{
role:"user",//用户
content:`请分析${data}中的数据,找出哪一条数据的name属性值等于
${query},将这条数据读取出来,存放在一个数组中,并返回给我,不要其他任何多余的文字,
结构如下:
{
data:[{
"id": 3,
"name" :"老",
"age" :30,
"address":"吉安"
}]
}`
}
],
model: "deepseek-chat",
})
console.log(users.choices[0].message.content);
res.end(users.choices[0].message.content)//将数据返回给前端
}
}
- 回到前端展示结果
js
window.onload =async function(){
const users =await fetchUsers('all')//获得到的用户信息
renderUsers(users)
}
function renderUsers(user){ //渲染用户信息
const tbody =document.querySelector('tbody') //获取tbody标签
tbody.innerHTML=''//清空表格内容
for (let i =0;i< user.length;i++){
const tr=document.createElement('tr')//创建一个tr标签
tr.innerHTML=`
<td>${user[i].id}</td>
<td>${user[i].name}</td>
<td>${user[i].age}</td>
<td>${user[i].address}</td>
`
tbody.appendChild(tr)//把tr塞到tbody里面
}
}
btn.addEventListener('click',async()=>{
const users =await fetchUsers(input.value)
renderUsers(users);//展示获取的数据
})
