加入收藏 | 设为首页 | 会员中心 | 我要投稿 汽车网 (https://www.0577qiche.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Ajax 前后端交互例子

发布时间:2023-04-06 08:55:32 所属栏目:教程 来源:
导读:首先我们先不去管如何向后端添加一条数据,我们来做一个简单的数据查询。

简单来说,前后端按顺序应该是这样的:

前端通过 Ajax 发送一个查询请求;
后端接收到请求,处理请求,包括 MysqL 查询等,最后返回结
首先我们先不去管如何向后端添加一条数据,我们来做一个简单的数据查询。

简单来说,前后端按顺序应该是这样的:

前端通过 Ajax 发送一个查询请求;
后端接收到请求,处理请求,包括 MysqL 查询等,最后返回结果;
前端收到请求,进行界面上的 table 更新。
Talk is cheap,接下来我们来实现一下。

获取服务端课程数据
const getValues = () => {
    return Ajax({
        method: 'get',
        url: '/course/get'
    })
}
这个方法我们返回Ajax请求对象,实际上是一个 promise,当服务端返回数据的时候,我们可以在后续的 ·then() 中进行表格更新。

这里要注意的是,由于 Ajax() 返回的是 promise, 所以 getValues() 返回的将会是个 promise。

表格更新
const updateTable = (data = []) => {
    const table = document.querySelector('#courseTable'); // 获取页面的table
    
    // table 的项, 这里初始化会添加表格头
    let tableItems = [
    `<tr>
        <th>课程名称</th>
        <th>老师</th>
        <th>开始时间</th>
        <th>结束时间</th>
    </tr>`];
    
    // 对数据做一个遍历, 处理为 HTML 字符串并添加到对应的 tableItems 的项中。
    data.forEach(item => {
        const {name, teacher, startTime, endTime} = item
        tableItems.push(
            `<tr>
                <td>${name}</td>
                <td>${teacher}</td>
                <td>${moment(startTime).format('YYYY-MM-DD')}</td>
                <td>${moment(endTime).format('YYYY-MM-DD')}</td>
            </tr>`
        );
        table.innerHTML = tableItems.join(''); // 数组转为字符串, 添加到 table 中
    })
}
表格更新函数接收一个数组数据,并且会遍历这个数组,分别把每一项处理为 HTML 字符串并添加到 tableItems 中。最后会把 tableItems 这个数组 通过 .join('') 的方式转化及拼接为一个 HTML 字符串,并添加到 table 中。

请求数据并更新表格
有了上面操作,一个负责获取数据,一个负责更新表格,那么我们可以合二为一,创造一个函数来控制流程。

const updateTableProcess = () => {
    return getValues().then(res => {
        const {code, data} = res
        if (code === ) { // 返回结果 code 为 0, 这里视为正确响应
            const {items} = data // 获取返回结果中的列表
            updateTable(items) // 更新表格
        }
    }).catch(e => {
        alert('获取数据失败啦')
    })
}
updateTableProcess(); // 执行
响应前端的请求
有求也要有应。服务端也需要在前端发出请求的时候做出相应的响应。

使用 node
const express = require("express");
const MysqL = require('MysqL');
const bodyParser = require("body-parser");
const router = express.Router(); // express 路由
const app = express();
// 使用 bodyParser 中间件
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
registerRouter();  // 路由注册执行
app.use(router); // 使用 router
/**
 * 构建返回结果
 * @param {*} code 
 * @param {*} data 
 * @param {*} error 
 */
const buildresponse = (code, data = {}, error = null) => {
    return {
        code,
        data,
        error
    }
}
// 创建 MysqL 链接, 本地数据库为 mk
const connection = MysqL.createConnection({
    host     : 'localhost',
    user     : 'root',
    password : 'ok36369ok',
    database : 'mk'
});
connection.connect();
// 端口号
const port = process.env.PORT || ;
// 监听
module.exports = app.listen(port, () => {
    console.log(`Server listening on http://localhost:${port}, Ctrl+C to stop`);
});
/***********路由注册模块*************/
/**
*路由注册函数
*/
function registerRouter() {
    // 查询课程
    router.get("/course/get", function(req, res) {
        connection.query('SELECT id, name, teacher, start_time as startTime, end_time as endTime from course', function (error, results, fields) {
            if (error) throw error;
            const responseData = buildresponse(, {items: results}) // MysqL 查询结果包装后进行返回
            res.send(responseData); // send 结果
        });
    });
    
    // other router ..
}
如上所示,我们引入了 Express 框架、bodyParser 以及 MysqL 相关的库。其中, bodyParser 可以解析请求中 body 的内容。 不过我们的重点应该是最下面的函数 registerRouter,这个函数是用来注册我们所有的路由的。我们之后的路由也都会写在这个函数里面。

好了,回归正题。为了使服务端响应前端的请求,我们在上面的代码中注册了一个路由:

 router.get("/course/get", callback)
如果前端发送请求到 “/course/get” ,那服务端会触发回调函数 callback,对应到上面代码中,我们可以看到:

内部会执行一个查询所有课程的 sql 语句;
将查询后的数据进行包装,变为 {code: 0, data: xxx, error: xxxx} 这样的格式;
返回数据。
相同的,我们也可以使用 java 来实现后端的逻辑。

使用 Java
package com.demo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.servletexception;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@WebServlet("/course/get")
public class HelloWorld extends HttpServlet {
    // JDBC 驱动名
    static final String JDBC_DRIVER = "com.MysqL.jdbc.Driver";
    // 数据库 URL
    static final String DB_URL = "jdbc:MysqL://localhost:3306/mk?useUnicode=true&useJDBCCompliantTimezoneshift\n" +
            "=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
    // 数据库的用户名
    static final String USER = "root";
    // 数据库的密码
    static final String PW = "ok36369ok";
    /**
    * 包装返回结果
    */
    private Map buildresponse(int code, Object data, String error) {
        Map<String, Object> res = new HashMap<String, Object>();
        res.put("code", code);
        res.put("data", data);
        res.put("error", error);
        return res;
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
    }
    // 获取课程使用 GET, 会进入 doGet
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws servletexception, IOException {
        Connection conn = null;
        Statement stmt = null;
        
        // 设置编码格式
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/json; charset=utf-8");
        PrintWriter out = response.getWriter();
        Map<String,Object> resMap = new HashMap<String,Object>(); // 返回结果, Map 类型
        try{
            // 注册 JDBC 驱动
            Class.forName(JDBC_DRIVER);
            // 打开链接
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(DB_URL,USER,PW);
            // 执行查询
            System.out.println(" 实例化Statement对象...");
            stmt = conn.createStatement();
            String sql;
            sql = "SELECT * FROM course";
            ResultSet rs = stmt.executeQuery(sql);
            List<Map> Courses = new ArrayList<Map>();
            // 展开结果集数据库
            while(rs.next()){
                // 通过字段检索
                Map<String,Object> map = new HashMap<String, Object>();
                int id  = rs.getInt("id");
                String name = rs.getString("name");
                String teacher = rs.getString("teacher");
                Date startTime = rs.getDate("start_time");
                Date endTime = rs.getDate("end_time");
                
                // 分别将 MysqL 查询结果 put 到 map中
                map.put("id", id);
                map.put("name", name);
                map.put("teacher", teacher);
                map.put("startTime", startTime);
                map.put("endTime", endTime);
                Courses.add(map);
            }
            Map<String, List> data = new HashMap<String, List>(); // 定义返回数据的 data部分, Map 类型
            data.put("items", Courses); // data 添加 items, items 就是我们要的课程列表数据
            // 构建输出数据
            resMap = buildresponse(, data, null);
            // 完成后关闭
            rs.close();
            stmt.close();
            conn.close();
        }catch(sqlException se){
            // 处理 JDBC 错误
            se.printstacktrace();
        }catch(Exception e){
            // 处理 Class.forName 错误
            e.printstacktrace();
        }finally{
            // 关闭资源
            try{
                if(stmt!=null) stmt.close();
            }catch(sqlException se2){
            }
            try{
                if(conn!=null) conn.close();
            }catch(sqlException se){
                se.printstacktrace();
            }
        }
        String responseData = JSON.toJSONString(resMap);// 将 Map 类型的结果序列化为 String
        out.println(responseData); // 返回结果
    }
}
这里主要使用的是 servlet 的方式来为前端提供服务,对于请求课程列表来说,使用到 GET 方法,因此本例子中会进入到 doGet 方法中。另外,所用到的技术在章节须知中也有讲到,这里就不再累赘。实现的代码虽然和 node 端有所差别,但是思想都是一样的。无非也是使用 MysqL 的查询结果, 拼装成前端所需要的数据。并进行返回。

(编辑:汽车网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章