一、express模块
1. 安装使用express
官网:Express官网
express是一个高度包容、快速而极简的 Node.js Web 框架。
Express 是一种保持最低程度规模的灵活 Node.js Web 应用程序框架,为 Web 和移动应用程序提供一组强大的功能。
使用express模块比http更加方便、简单。
安装:
npm init -y
npm install express --save
使用:
// 引入express
const express = require("express");
// 使用express用于创建服务器应用
const app = express(); // 执行函数,返回函数内部方法
// 启动应用程序,监听3000端口
app.listen("3000", () => {
console.log("3000端口已经开启")
});
想要页面地址栏访问时获取数据 => 配置对应的地址,配置对应的路由:
app.get("/", (req, res) => {
// res.send() 向前端发送数据:字符串 对象 数组 buffer
res.send("云想衣裳花想容,春风扶槛露华浓。")
});
前端页面发送get时,进入app.get进行路由匹配,/根路由就是启动路由地址:http:localhost:3000
注意:http模块向前端发送数据用res.end,而express用的是res.send;且http模块在发送数据前需要设置响应头让前端按照格式进行解析,而express不需要。
// 让前端按照该格式进行解析
response.setHeader("Content-Type", "text/html;charset=utf-8");
2. 设置跨域
使用前端html页面访问后端数据:
<body>
<button id="box">get请求1</button>
<br />
<script src="https: //unpkg.com/axios/dist/axios.min.js"></script>
<script>
// 向后端 / 根路由发起请求
box.onclick = () => {
axios({
method: 'get',
url: "http://localhost:3000",
}).then(res => {
console.log(res.data)
})
};
</script>
</body>
显示跨域错误:
设置跨域头:
// 设置允许任何人都可以访问
res.header("Access-Control-Allow-Origin", "*");
但是如果我们在根路由的基础上多配置几个访问路径,那么每个路径的后端都需要设置跨域响应头,较为麻烦,例如:
解决:
express中有all方法,用于解决每返回一个地址就要加一个解决跨域的麻烦:
app.all("*", (req, res, next) => {
// * 可以理解为一个变量,第三个参数next执行下一个请求方式相同的路由地址
// 设置允许任何人都可以访问
res.header("Access-Control-Allow-Origin", "*");
console.log("所有路由经过地", req.url); // 这里的路由是不可以变化的
next(); // 执行下一个get请求方式和all里面的req.url相同的路由地址
});
注意:该方法一定要添加next参数并调用,否则不会返回数据到前端。
结果显示:
后端完整代码:
const express = require("express");
const app = express();
app.all("*", (req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
console.log("所有路由经过地", req.url);
next();
});
app.get("/", (req, res) => {
res.send("云想衣裳花想容,春风扶槛露华浓。")
});
app.get("/test1", (req, res) => {
res.send("若非群玉山头见,会向瑶台月下逢。")
});
app.get("/test2", (req, res) => {
res.send("天生我材必有用,千金散尽还复来。")
});
app.listen("3000", () => {
console.log("3000端口已经开启")
});
二、中间件
1. 跨域中间件
CORS 是一个node.js包,用于提供连接/高速中间件,可用于启用具有各种选项的 CORS。
安装和使用:
npm i cors -S
后端js代码优化为:
const express = require("express");
const app = express();
const cors = require("cors"); // 引入core跨域中间件包
app.use(cors()); // express 提供使用中间件的方法
app.get("/", (req, res) => {
res.send("云想衣裳花想容,春风扶槛露华浓。")
});
app.get("/test1", (req, res) => {
res.send("若非群玉山头见,会向瑶台月下逢。")
});
app.get("/test2", (req, res) => {
res.send("天生我材必有用,千金散尽还复来。")
});
app.listen("3000", () => {
console.log("3000端口已经开启")
});
成功渲染数据:
中间件原理: 关键在next()这个方法会执行下一个和当前请求方式(get或post)一样的路由地址,前端发送请求的时候后端可以通过设置中间件处理各种问题,同时前端的请求会先提交到第一个中间件函数,再通过next() 执行自定义配置的路由地址。
其实我们还可以发现,前端html页面每一个点击事件中都会重复的写根路由 http://localhost:3000;
而跟路由可以用/表示,所以我们可以配置全局默认配置:
// 设置axios 全局默认配置
axios.defaults.baseURL = "http://localhost:3000";
前端html代码:
<body>
<button id="box1">get请求1</button>
<br />
<button id="box2">get请求2</button>
<br />
<button id="box3">get请求3</button>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 设置axios 全局默认配置
axios.defaults.baseURL = "http://localhost:3000";
// 向后端 / 根路由发起请求
box1.onclick = () => {
axios({
method: 'get',
url: "/",
}).then(res => {
console.log(res.data)
})
};
box2.onclick = () => {
axios({
method: 'get',
url: "/test1",
}).then(res => {
console.log(res.data)
})
}
box3.onclick = () => {
axios({
method: 'get',
url: "/test2",
}).then(res => {
console.log(res.data)
})
}
</script>
</body>
2. 后端获取前端发送的数据
2.1 get方式
前端在点击事件中使用params参数发送数据给后端:
box2.onclick = () => {
axios({
method: 'get',
url: "/test1",
params: {
name: "LeBron James",
age: "38",
pro: "player",
}
}).then(res => {
console.log(res.data)
})
}
后端通过req.query的方法获取前端发送的的数据
app.get("/test1", (req, res) => {
res.send("若非群玉山头见,会向瑶台月下逢。");
console.log(req.query);
});
打印输出:
2.2 post方式
express规定get请求和post请求是互相独立的,各自发起请求的,但all.use()方法都接收这里种请求。
所以我们只需修改get请求,不需修改中间件。
且前端post是通过data参数发送数据,后端post通过req.body接收数据,另外需要配置中间件进行解码。
// 使后端获取前端发送来的post数据
app.use(express.urlencoded({extended:true})); // 通过中间件解码post请求的数据
app.use(express.json());// post数据json化
前端post请求代码:
<button id="box4">get请求4</button>
<script>
box4.onclick = () => {
axios({
method: 'post',
url: "/test_post",
data: {
name: "Kobe Bryant",
age: "41",
pro: "player",
}
}).then(res => {
console.log(res.data)
})
}
</script>
后端post接收代码:
app.use(express.urlencoded({extended:true})); // 通过中间件解码post请求的数据
app.use(express.json());// post数据json化
app.post("/test_post", (req, res) => {
res.send("沉舟侧畔千帆过,病树前头万木春。");
console.log(req.body);
});
渲染结果:
打印输出:
不过其实我发现如果只把get改成post,只要前端发送用params,后端接收用req.query,后端就能获取到数据。而且这样也不用设置解码等操作。