项目开发之——后端

接口 ??前后端的通讯,大部分来讲,是通过接口。接口通俗来讲,就是一个函数,有输入参数,有返回数据,与一般编程时所用到的函数不同在于,前端相当于只有一个可以调用的函数名(链接),这个接口可以返回一个完整的html页面,也可以返回一段数据(json数据),总之,这个函数必须要有返回,哪怕只是一个成功提示
get和post
??最基础的2种请求方式,其区别在于参数传递的显式和隐式,二者详细区别见此文
get ??显式传递参数的请求方式,参数直接在链接中表示,例如向https://baidu.com/get-test接口发送参数为{haoye:"blabla"}的请求
??请求代码示范:(此处使用axios请求工具)

axios.get("https://baidu.com/get-test?haoye=blabla").then(r=>{ // 此处使用的函数为promise形式 console.log(r.data) // 在此处处理返回结果 })

??之所以为显式,是因为这种请求方式,使用该方式发送请求,和直接浏览器进入https://baidu.com/get-test?haoye=blabla是等效的,返回的内容是一样的,所需的参数均已包含在了链接中。
??参数的表示形式为请求链接(域名+请求地址)后?隔开,key=value形式,不同参数间以&隔开,例如以上例子:https://baidu.com/get-test?haoye=blabla&haoye2=2,即为向https://baidu.com/get-test接口发送请求,参数为{haoye:"blabla",haoye2:2}(链接中不必注明参数类型,均为字符串,交付于后端解析,此为解析后结果)
post ??隐式参数传递的请求方式,参数包裹在请求体中,例如向https://baidu.com/post-test接口发送参数为{haoye:"blabla"}的请求
??请求代码示范:(此处使用axios请求工具)
axios.post("https://baidu.com/post-test",{haoye:"blabla"}).then(r=>{ // 此处使用的函数为promise形式 console.log(r.data) // 在此处处理返回结果 })

??之所以为隐式,是因为这种请求方式,参数不予以展示在链接中,而是包含在请求体中,直接在浏览器中输入链接就不好使了,因为后台缺少haoye这一参数,不会有正常的返回了
后端接收
??前端的请求发来了,后端需要怎么接收呢?
??首先,接口是建立在一个运行中的服务器上的;其次,服务器监听当前这个ip接收到的请求,检测这个请求中所包含的路由地址,而这个路由地址,就是我们定义的接口的名称;通过编写相应的程序,建立一个监听请求的服务器,识别请求的路由地址,并做相应返回,即完成了接口的编写;
??那么如何编写接口?例如在Java的spring框架中
@RestController public class MyGetMethod { @RequestMapping(value = "https://www.it610.com/get-test",method = RequestMethod.GET) public String getwithParam(@RequestParam("haoye") String haoye){//get接口 return "我收到了参数haoye:" + haoye; } }

??在nodejs的express框架中
app.get("/get-test", async (req,res)=>{ const haoye = req.query.haoye res.send("我收到了参数haoye:" + haoye; ) }) app.post("/post-test", async (req,res)=>{ const haoye = req.body.haoye res.send("我收到了参数haoye:" + haoye; ) })

??当然还有其他的常用的后台语言,例如golang,天下最好的php,python(django框架),当然甚至可以用C语言、汇编等,但建议不要和自己过不去
??PS:可以看出,在node中,接收参数的方式较java更自由一些,即使是post类型的链接,带上get类型的参数,也可以通过.query获取,get和post本质上就是两种参数传递的形式;但实际应用中不建议这样混写,降低可读性以及不方便接口的调用。
接口测试
??通常前端开发需要测试后端开发的某个接口,包括接口监控和接口测试;
??首先接口监控,在前端开发调试或写爬虫的观察阶段(爬虫写的好,牢饭吃到饱)时,如何查看用某个接口发送了什么参数的请求?
  • 浏览器控制台source页面,以下随机抓取一个受害网站:
【项目开发之——后端】??可以看到,在这里可以设置断点,对代码进行调试
项目开发之——后端
文章图片

??但是问题来了,如果懒得调试代码,或者为防止源码泄露和初级爬虫,代码是压缩过的没法看怎么办?
  • 控制台的network页面,随机抓取一个受害网站:
??可以看出,一般网页在打开时为获取资源都发送了不少请求,可以通过preview来预览请求的内容,或是页面或是数据,具体哪个是你想要查看的接口,花耐心找就好
项目开发之——后端
文章图片

??再一个便是接口调用测试,get类型的接口可以直接通过浏览器输入测试,但是post呢?而且如果get需要某个重要的请求头呢?这些都是没法直接在链接中表示的
??此处推荐postman这一接口测试利器,高效测试项目的接口
衍生请求方式
??随着前端的发展,get和post不仅仅只有他们通讯协议层面的含义了,同时也具有了业务逻辑层面的含义,于是就有了一套get、post、delete、put/patch的rest风格接口,这些方式仅为一个标准(当然有实现了此标准的插件),参照这个标准这个执行过程来编写后台程序会相较于传统的接口开发更为高效
??get除表示显式请求外,还表示从服务器获取一定的资源;仅仅只是获取,不对后端的数据库做任何改动
??post除表示隐式请求外,还表示要往后台的数据库中新插入一条数据
??由此衍生出了delete,顾名思义,要从数据库中删除一条数据;delete本质上还是get请求,但是delete的参数在路由中,例如/delete-test/1,意为调用delete-test接口,删除id为1的某条数据;为防止没有权限的用户调用此方法,通常需要在请求头中携带相关token才可正常调用此接口
??以此类推,put/patch为将某一条数据覆盖,其区别在于put需要提供那条数据的全部字段信息,而patch只需要提供需要修改的字段,调用方式为首先路由中声明id,/put-test/1/patch-test/1,再隐式提供需要修改的数据
框架 ??作为一个合格的后台,需要做到的事包括
  1. 能够启动程序监听计算机某个端口的全部请求
  2. 能够解析这些请求,依照http标准作出正确的判断和处理
  3. 能够处理这些请求,并依照http标准返回数据
??能够实现以上这些需求,就可以实现一个简单的后台服务器了,所以任何语言都可以写后端;但这些需求如果亲自动手实现的话将是一个巨大的工程,不过好在已经有大把好心人帮助我们实现了这些功能,而实现了一些常用需求的外部包一般称之为框架
??以nodejs为例,nodejs中可用于搭建后台服务器的框架包括express,koa,socket.io,hapi等,以express为例,参考第二篇第一个nodejs程序,详细展开讲解其中的代码
const express=require('express'), bodyParser = require('body-parser'); const app=express()//使用express这个函数app.use(bodyParser.json()); // 调用一个插件,使接收到的请求体中的数据能够自动转换为json格式 app.use(express.static(path.join(__dirname, 'public'))); // 托管静态资源,托管的这些资源,即为全部的前端代码了,此处采用前后端分离式的开发async function signIn(request, response) { // 此处定义一个函数 const identifier = request.body.identifier, password = request.body.password login({identifier, password}).then(r => { let user = r.user; user = optimiseUser(user); response.send({ success: true, info: r }); }).catch(error => { const message = getErrorMessage(error); response.send({ error: message }); }); }app.post('/signIn', signIn); // 此处为服务器新增一个signIn接口,处理函数即为上方定义的函数app.listen(8080) // 开启服务器,监听8080端口console.log("success") //成功提示

??可以看出,signIn接口接收的参数只有identifier以及password,返回的参数为
{ success:true, info:{user:{}}, error:"message" }

??也就是说,只要前后端约定好,这个接口名为signIn,接收参数为identifier以及password,返回数据为{success:true,info:{user:{}},error:"message"},前后端就可以各自开始自己关于登录相关代码的编写了;
??以此类推,在开发前,只需要以这个标准,设计好关于这个项目的全部的接口,前后端即可同时开始开发互不干扰了,上线前测试一下即可,了解了这些,基本上就可以开发一个项目出来了;
cms ??对于一些中小型,数据结构符合传统sql数据库,增删查改需求简单,懒得写代码的项目,现在有了一个一站式的解决方案——CMS(Content Management System),即内容管理系统,起初是用于个人博客的搭建,后来逐渐衍生出了一些新功能,更加专注于内容而不是页面,于是便有了headless CMS,即其中只有数据内容,不关注数据库用的什么,也不关注页面长什么样,属于无头状态,开始适用于一些中小型的项目开发;一个合格的cms应做到以下几点:
  1. 不需要手动编写即可创建数据库,并对数据库有着可视化增删查改全方位的管理功能
  2. 针对数据库中的每个表格都能够提供restful接口以及文档来方便调用
  3. 提供大部分项目需要的一些常见功能,例如:用户登录、身份权限管理、用户真人身份邮箱验证
  4. 提供可靠的文件管理系统
??一些常见的开源cms在此,强烈推荐strapi,功能强大,使用方便,对restful接口提供着完整的支持,在此查看strapi中restful接口的一些额外查询功能;有着完整的登录和权限管理模块;并有着强大的关系型数据库建立功能

    推荐阅读