express基础知识(二) | 青训营笔记

117 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的的第12天

本篇继续讲 express 的基础知识。 上一篇:express基础知识(一) | 青训营笔记 - 掘金 (juejin.cn)

编写接口

编写GET请求

express.js

const express = require('express');

const app = express();

const router = require('./apiRouter');

app.use('/api',router);

app.listen(8888,()=>{
    console.log('http://127.0.0.1');
})

apiRouter.js

const express = require("express");

const router = express.Router();

//在这里挂载对应的路由
router.get("/get", (req, res) => {
  //通过 req.query 获取客户端通过查询字符串,发送到服务器数据
  const query = req.query;
  //调用 res.send() 方法,想客户端响应处理的结果
  res.send({
    status: 0,
    msg: "GET请求成功!", //状态的描述
    data: query, //需要响应给服务器的数据
  });
});

module.exports = router;

expressGET接口.png

编写POST接口

express.js

const express = require('express');

const app = express();

const router = require('./apiRouter');

//一定要加这个,否则无法响应 data 数据
app.use(express.urlencoded())

app.use('/api',router);

app.listen(8888,()=>{
    console.log('http://127.0.0.1');
})

apiRouter.js

const express = require("express");

const router = express.Router();

// 定义 POST 接口
router.post("/post", (req, res) => {
  // 通过 req.body 获取请求体中包含的 url-encoded 格式的数据
  const body = req.body;
  // 调用 res.send() 方法,向客户端响应结果
  res.send({
    status: 0,
    msg: "POST 请求成功!",
    data: body,
  });
});

module.exports = router;

expressPOST接口.png

跨域

接口跨域问题的暴露

<body>
    <button id="btnGET">GET</button>
    <button id="btnPOST">POST</button>
​
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
        $('#btnGET').on('click', () => {
            $.ajax({
                type: 'GET',
                url: 'http://127.0.0.1:8000/api/get',
                data: {
                    name: 'zs',
                    age: 20
                },
                success: (res) => {
                    console.log(res);
                }
            })
        })
​
        $('#btnPOST').on('click', () => {
            $.ajax({
                type: 'POST',
                url: 'http://127.0.0.1:8000/api/post',
                data: {
                    name: 'ls',
                    age: 30
                },
                success: (res) => {
                    console.log(res);
                }
            })
        })
    </script></body>

Snipaste_2022-08-24_14-40-42.png

刚刚编写的 GET 和 POST 请求,存在一个很严重的问题:不支持跨域请求。

使用CORS中间件解决跨域问题

CORS是express的一个第三方中间件。通过安装和配置CORS中间件,跨域很方便地解决跨域问题。

  • 运行 npm i cors 安装中间件
  • 使用 const cors = require('cors') 导入中间件
  • 在路由之前调用 app.use(cors()) 配置中间件
const express = require("express");
// 导入 cors
const cors = require("cors")

const app = express();

// 使用 cors 一定要在路由之前
app.use(cors())
const router = require("./apiRouter");

app.use(express.urlencoded())

app.use("/api", router);

app.listen(8000, () => {
  console.log("http://127.0.0.1");
});

什么是CORS?

CORS(跨域资源共享)由一系列 HTTP响应头 组成,这些 HTTP 响应头决定浏览器是否阻止前端js代码跨域请求资源

浏览器的 同源安全策略 默认会阻止网页“跨域”获取资源。但如果接口服务器配置了CORS相关的HTTP响应头,就可以解决浏览器端的跨域访问限制。

Snipaste_2022-08-24_14-50-46.png

注意点:

  • cors主要在服务器端进行配置,客户端浏览器无需做任何额外的配置,即可请求开启cors接口
  • cors具有兼容性问题

使用 jsonp 解决跨问题

概念:浏览器通过 <script> 标签的 src 属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种请求数据的方式叫做JSONP。

基本原理 : 主要就是利用了 script 标签的src没有跨域限制来完成的。

执行过程

  • 前端定义一个解析函数(如: jsonpCallback = function (res) {})
  • 通过params的形式包装script标签的请求参数,并且声明执行函数(如cb=jsonpCallback)
  • 后端获取到前端声明的执行函数(jsonpCallback),并以带上参数且调用执行函数的方式传递给前端
  • 前端在script标签返回资源的时候就会去执行jsonpCallback并通过回调函数的方式拿到数据了。

特点

  • JSONP不属于真正的 Ajax 请求,因为它没有使用XMLHttpRequest这个对象。
  • JSONP仅支持GET请求,不支持POST,PUT,DELETE等请求。

实现:

jsonp.html

<!DOCTYPE html>
<html lang="en">

<head>
    <title>测试接口跨域问题</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="css/style.css" rel="stylesheet">
</head>

<body>
    <button id="btnJsonP">JsonP</button>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
        $('#btnJsonP').on('click', () => {
            $.ajax({
                type: 'GET',
                url: 'http://127.0.0.1:8000/api/jsonp',
                dataType:'jsonp',
                success: (res) => {
                    console.log(res);
                }
            })
        })

    </script>

</body>

</html>

jsonp.js

const express = require("express");

const app = express();

app.use(express.urlencoded({ extended:false }))

app.get('/api/jsonp',(req,res)=>{
    // 1.得到函数的名称
    const funcName = req.query.callback
    // 2.定义要发送到客户端的数据对象
    const data = { name:'zs',age:20 }
    // 3.拼接处一个函数的调用
    const scriptStr = `${funcName}(${JSON.stringify(data)})`
    // 4.把拼接的字符串,响应给客户端
    res.send(scriptStr)
})

app.listen(8000, () => {
  console.log("http://127.0.0.1");
});

注意事项: 如果项目中已经设置了CORS跨域资源共享,为了防止冲突,必须在配置CORS中间件之前生命JSONP的接口。否则JSONP接口会被处理成开启了CORS的接口。

与 mysql 连接

安装

npm i mysql

简单的一个实例

var mysql = require("mysql");
var connection = mysql.createConnection({
  host: "localhost", // 主机名
  port: 3306, // MySQL 默认端口为 3306
  user: "root", // 使用 root 用户登入 MySQL
  password: "admin", // MySQL 密码,用你自己的
  database: "demo", // 使用数据库
});

connection.connect(function (error) {
  if (error) throw error;
  console.log("[connection connect] succceed ");
});

// 所执行的sql语句
connection.query("select * from user", function (error, results) {
  if (error) throw error;
  console.log("The solution is: ", results);
});

connection.end(function (error) {
  if (error) throw error;
  console.log("[connection end] succeed ");
});

Snipaste_2022-08-24_17-52-10.png

查询数据

connection.query("select * from user", (err,results)=>{
    if(err){
        return console.log(err.message)
    }
    console.log(results)
});

Snipaste_2022-08-24_20-58-57.png

插入数据

const user = { name:'叶老板',age:19 }
const sqlStr = 'insert into user (name,age) values (?,?)'
connection.query(sqlStr,[user.name,user.age], (err,results)=>{
    if(err){
        return console.log(err.message)
    }
    // 注意:如果执行的是 insert into 插入语句,则 result 是一个对象
    if(results.affectedRows === 1){
      console.log('插入数据成功')
    }
});

Snipaste_2022-08-24_21-09-47.png

Snipaste_2022-08-24_21-09-38.png

当向表中新增数据时,如果 数据对象的每个属性数据表的字段 一一对应 ,则可以通过如下的方式插入数据。

const user = { name:'杨洋阳',age:29 }
const sqlStr = 'insert into user set ?'
connection.query(sqlStr,user, (err,results)=>{
    if(err){
        return console.log(err.message)
    }
    // 注意:如果执行的是 insert into 插入语句,则 result 是一个对象
    if(results.affectedRows === 1){
      console.log('插入数据成功')
    }
});

更新数据

const user = { id: 2, name: "aaa", age: 39 };

const sqlStr = `UPDATE user SET name = ? WHERE id = ?`;

connection.query(sqlStr, [user.name, user.id], (err, results) => {
  if (err) {
    return console.log(err.message);
  }
  if (results.affectedRows === 1) {
    console.log("更新数据成功");
  }
});

当然,更新数据也有简便操作

const user = { id: 2, name: "bbb", age: 39 };

const sqlStr = `UPDATE user SET ? WHERE id = ?`;

connection.query(sqlStr, [user, user.id], (err, results) => {
  if (err) {
    return console.log(err.message);
  }
  if (results.affectedRows === 1) {
    console.log("更新数据成功");
  }
});

删除数据

const sqlStr = `delete from user where id = ?`;

connection.query(sqlStr, 6, (err, results) => {
  if (err) {
    return console.log(err.message);
  }
  if (results.affectedRows === 1) {
    console.log("删除数据成功");
  }
});

结语

文章如果有不正确的地方,欢迎指正,共同学习,共同进步。

若有侵权,请联系作者删除。