感谢b站up主技术蛋老师的精彩分享!
前后端
前端即用户的设备,给这些设备开发浏览器网页、app、小程序就叫前端开发;主要是处理用户界面和交互逻辑。
后端就是服务器、网络、数据库,运行在服务器上的程序就叫服务,主要是处理数据库和安全。
软件开发方式
- 前后端不分离
传统开发方式是侧重于后端的业务逻辑处理上,用模板嵌套方式绑定数据(公司官网、个人主页)
随着移动互联网的发展,前端发展迅猛,技术栈也愈加丰富,体量俞大。前端就不能零散的分布在整个系统架构中了,也应该像后端一样实现工程化、模块化、系统化。
基于上述的环境变化,在软件工程项目管理工作上需要一种开发方式的升级,也是公司架构的一种调整。
- 前后端分离
前端剥离独立出来的一种开发方式:前端用vue或react创建一个前端项目,后端用java或go或php创建一个单独的后端项目,前后端定一个数据接口,前端要显示数据时,用AJAX发送请求向后台拿数据(异步的数据)。
典型应用场景:后台管理系统、手机应用
前后端分离的缺点:SEO不友好,易出错,但是vue和react用到SSR服务端渲染很好地解决了这个缺点。
前后端分离的原因
1. 数据需要集中储存
数据保存集中保存在服务器上。
2. 安全
前端只发送固定的参数,接收结果的数据,用户通过不同的API接口,完成各种数据功能的同时,不用理会内部代码怎样。
前端代码所有人可以看到,若直接连接数据库,密码直接泄露,所以后端会开启一个服务(API应用程序接口),公开一个网络地址,API会判断前端发过来不同的网络请求数据,分别调用对应的函数或其他服务。这些函数根据传来的参数去操作数据库进程处理。
3. 权限管理
前后端交互
数据都保存在环境内存中,刷新或重启后,一切数据会回到刚打开的状态。所以用浏览器的localStorage函数来保存和查询数据:
本地存储 localStorage
前端数据库保存在浏览器里
| localStorage对象 | 功能 | 接收参数 |
|---|---|---|
| getItem函数 | 获取项 item | 1数据名称 |
| setItem函数 | 保存数据 | 1数据名称 2数据的值 |
| removeItem函数 | 删除项 item | 1数据名称 |
let youShi = false;
function change(){
let anNiu = document.getElementById("anNiu");
let shuRuKuang = document.getElementById("shuRuKuang");
if(youShi){
youShi = false;
anNiu.innerText = "√";
shuRuKuang.style.borderBottomColor = '#fff';
shuRuKuang.value = "";
shuRuKuang.readOnly = false;
window.localStorage.removeItem('shi')
} else {
youShi = true;
anNiu.innerText = "×";
shuRuKuang.style.borderBottomColor = 'transparent';
shuRuKuang.readOnly = true;
// 内容保存到本地存储里,setItem接收两个参数,数据名称和数据的值
window.localStorage.setItem("shi",shuRuKuang.value);
}
}
// localStorage对象的getItem函数就是获取项 item 接收一个参数,即数据名称
let date = window.localStorage.getItem("shi");
// 每次打开时,查询浏览器localStorage是否有数据,有就显示出来。
if(data){
document.getElementById("shuRuKuang").value = data;
change();
}
前后端交互
// server.js
// 引用两个后端node.js框架内置的库:http和fs,即别人写好的对象和函数
// require 是引用库的框架自带函数
// http用来创建http服务
let http = require("http");
// fs = file system 用来操作文件
let fs = require("fs");
// req是发进来的网络请求数据,res是返回数据的函数
// 用 res.writeHead 统一设置返回的网络请求头
function houDuan(req, res){
res.writeHead(200, {
"Content-Type":"application/json;charset=utf-8", // 内容类型json格式
"Access-Control-Allow-Methods":"*", // 允许请求方式, * 允许所有
"Access-Control-Allow-Origin":"*", // 允许请求来源
});
// 如果来的网络请求是 GET 方法,那么直接 end 返回文字数据
if(req.method === "GET"){
if(fs.existsSync("wenZi.txt")){
// 用fs的readFileSync同步读取文件函数,第一个参数文件路径
let wenZi = fs.readFileSync("wenZi.txt", "utf8").toString();
res.end(JSON.stringify({data: wenZi}));
} else {
res.end("{}");
}
// 如果来的网络请求是 POST 方法,那么就获取传入的url参数
} else if(req.method === "POST"){
let xinWenZi = decodeURI(req.url.substring(1));
// 调用fs的写文件函数把数据写入文件
fs.writeFileSync("wenZi.txt", xinWenZi);
res.end("{}");
// 如果来的网络请求是 DELETE 方法,那么就直接调用fs的写文件函数把空数据写入文件
} else if(req.method === "DELETE"){
fs.writeFileSync("wenZi.txt", "");
res.end("{}");
} else {
// 其他方法一律返回空json对象
res.end("{}");
}
}
// http对象的createServer函数创建了一个server服务
// 这个服务的所有逻辑交给houDuan函数处理,请求来的数据和返回的函数会传入houDuan函数
// 监听listen在3000端口上,一直会接收发到3000端口的网络请求
http.createServer(houDuan).listen(3000);
console.log("服务启动,地址:http://localhost:3000/");
替换本地存储为fetch函数
原来用localStorage函数操作浏览器数据库实现增删改查数据,现在用fetch网络通信函数给后端服务,后端对请求来的数据进行判断后,再调用fs函数增删改查实际的文件数据,实现了前端不直接操作数据库,在保证安全的情况下,完成数据的统一存取。