【REST系列】C/S(B/S)架构和web“前后端分离“的联系 ——REST‘C/S约束‘知识扩充


REST的第一条约束:Client-Server,也就是C/S架构

论文原文 5.1.2 Client-server
在这里插入图片描述
这条约束取自 3.4.1小节
在这里插入图片描述

C/S架构分离了客户端和服务器的关注点,使得他们可独立地进化
目前服务器和客户端的进化表现为:

  • 服务器关注数据处理。用集群、分布式、微服务等技术来提高处理速度和稳定性。
  • 客户端关注用户界面。因为客户端直接与人交互,涉及到人们的各种需求,所以发展的非常丰富:桌面应用、浏览器、手机App、智能穿戴设备App、小程序等等。

客户端和服务器通过网络接口来进行通信,这种促进服务器和客户端独立进化的软件架构,提高了web的丰富性

C/S(B/S)约束 和 web的"前后端分离" 的联系

"前后端分离"是B/S架构上的概念。B/S架构属于C/S的变种,他们有一些差异:

  • B/S相比于C/S 最大的好处是:用户仅需要安装一个浏览器,就可以使用各种各样的网络服务,而不需要下载专门的客户端软件;开发人员也不需要考虑客户端的跨平台的问题,只需要浏览器厂商开发不同平台上的浏览器即可
  • 在提供用户界面的方式上:C/S的用户界面完全构建在客户端,而B/S的用户界面则需要浏览器向服务器请求

为什么要讨论 C/S约束 和 “前后端分离”?
我认为它们是有联系的,根据C/S约束的描述,可以套用:“前后端不分离”,会限制服务器的进化,降低用户界面的可移植性

在"前后端分离技术"时代之前,是"动态页面技术"时代,是"前后端不分离"的

web前端发展过程
web最早期是静态网页时代,静态网站只能够根据用户的请求返回指向的网页,除了进行超链接跳转,没办法实现任何交互
为了做到用户和网站的动态交互,出现了以3P(PHP、JSP、ASP)为代表的"动态页面技术"
这些服务器端的动态页面技术使得网页可以获取服务器的数据并保持动态更新,推动了Google为代表的搜索引擎和各种论坛的出现,万维网开始快速发展

动态页面技术(非前后端分离)的缺点

  1. 限制了服务器的进化。它降低了服务器的专注性,服务器不仅要进行数据处理,还要渲染出HTML代码发送给客户端。
  2. 降低了用户界面的可移植性。用户界面跨平台移植意味着,用户界面可以做到一次编写就能部署到多个平台。这要求客户端具备相当的独立进化能力。前后端不分离时,前端代码必须要在后端编写,甚至前端代码会和后端代码同时写在一个文件里。这极大地限制了前端的进化能力,它并不是一个独立的组件,很难进化出可移植能力。
    另外,B/S的请求需要接口返回嵌入了数据的HTML代码,而C/S则只需要返回纯数据,所以他们的接口是不通用的,需要分别写接口。分别写接口又进一步限制了服务器的进化,因为返回HTML代码的数据量比只返回纯数据的数据量大得多,给服务器的带来的压力更大,两种数据量差异很大的接口同时存在,降低了对服务器压力预判的可靠性 (所以当时最好的做法可能是单独写个B/S端的服务器组件,代理C/S的纯数据接口返回HTML页面)
  3. 开发模式不专业。前端代码要在服务端工程中开发,要么需要服务端懂前端,要么需要前端懂服务端。随着前端发展的越来越完善、庞大,这种开发方式也越来越不专业。

直到Ajax的出现,让前后端分离成为了可能

Ajax 和 “前后端分离”
Ajax由微软开发,从1998年开始初步应用,但当时并没有火(好像是因为速度比较慢,人们对交互的需求也还不高)。
直到2005年初,Google在它发布的著名的交互应用程序(Google Map、Gmail、Google讨论组、Google搜索建议等)中大量使用了Ajax异步通讯,这让页面无需刷新就可以发起HTTP请求,用户也不用专门等待请求的响应,而是可以继续网页的浏览或操作。
Google在当时可以说将Ajax运用到了登峰造极的地步,突然间刺激了人们的神经,刷新了交互的需求,开发者们迅速关注起Ajax。从此Ajax开始普及,AJAX的广泛使用,标志了 Web2.0 时代的开启。
得益于AJax的异步通讯,前端技术发展的越来越快,专业的web前端工程师也开始出现。前端为了寻求良好的可维护性和可复用性,也不得不参考后端 MVC 进行了设计和拆分,后来出现了三大前端框架:AngularJS(2009)、React(2010)、Vue(2014),"前后端分离的时代"正式来临

所以,"前后端分离"更加符合C/S约束,更加有利于服务端和客户端组件的独立进化。服务端有了更强的伸缩性,客户端也更加专业和丰富。现在的多平台客户端:百度网盘、爱奇艺等等,它们可以在网页、桌面应用、手机App等平台使用,所有平台上的同样功能调用的都是同一个接口

“前后端分离”,是一定意义上的C/S

B/S架构其实无论怎样都做不到像C/S架构一样真正的客户端-服务器分离,因为浏览器不可能保存所有网站的用户界面,用户界面必须向服务器请求。

但是我们可以变通地将"服务器"分为:“用户界面服务器” 和 “数据服务器”。事实也是如此,这个"用户界面服务器"叫做"静态资源服务器"

利用"前后端分离"开发出来的程序,可以将前端工程部署到专门的静态资源服务器(Apache、Nginx)。

这就实现了一定意义上的 “客户端-服务器分离”:客户端由 浏览器 + 静态资源服务器 组成,数据服务器专心做数据处理


  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的B/S架构实现的代码用例,使用Java语言和Spring框架: 1. 前端代码(HTML、CSS、JavaScript): ```html <!DOCTYPE html> <html> <head> <title>B/S Architecture Example</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"> </head> <body> <div class="container mt-5"> <h1>B/S Architecture Example</h1> <div class="form-group"> <label for="input-text">Enter some text:</label> <input type="text" class="form-control" id="input-text" placeholder="Type something..."> </div> <button type="button" class="btn btn-primary" onclick="sendText()">Send</button> <hr> <div id="output"></div> </div> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.2.0/dist/tf.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/universal-sentence-encoder@4.2.0/dist/universal-sentence-encoder.min.js"></script> <script src="app.js"></script> </body> </html> ``` 2. 后端代码(Java + Spring): ```java package com.example.bsaexample; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import org.tensorflow.Tensor; import org.tensorflow.Tensors; import org.tensorflow.framework.ConfigProto; import org.tensorflow.framework.GPUOptions; import org.tensorflow.framework.Session; import org.tensorflow.framework.Session.Runner; import org.tensorflow.framework.TensorShape; import java.util.Arrays; @SpringBootApplication @RestController public class BsaExampleApplication { public static void main(String[] args) { SpringApplication.run(BsaExampleApplication.class, args); } @PostMapping(value = "/predict", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public String predict(@RequestBody String input) { GPUOptions gpuOptions = GPUOptions.newBuilder().setVisibleDeviceList("0").build(); ConfigProto configProto = ConfigProto.newBuilder().setGpuOptions(gpuOptions).build(); try (Session session = Session.create(configProto.toByteArray())) { Tensor<String> inputTensor = Tensors.create(new String[] { input }); Runner runner = session.runner().feed("input", inputTensor).fetch("output"); Tensor<Float> outputTensor = runner.run().get(0).expect(Float.class); float[] output = outputTensor.copyTo(new float[1][512])[0]; return Arrays.toString(output); } catch (Exception e) { e.printStackTrace(); return "Error: " + e.getMessage(); } } } ``` 3. 前后端交互代码(JavaScript): ```javascript async function sendText() { const input = $("#input-text").val(); if (input.trim() !== "") { $("#output").text("Loading..."); const output = await predict(input); $("#output").text(output); } } async function predict(input) { const model = await tf.loadGraphModel("model/model.json"); const encoder = await use.load(); const encodedInput = await encoder.embed([ input ]); const inputTensor = tf.tensor(encodedInput); const outputTensor = model.execute({ "input": inputTensor }); const output = await outputTensor.array(); return output; } ``` 这个例子实现了一个简单的文本编码预测功能,用户在前端输入一段文本,通过JavaScript调用后端的REST API进行计算,后端使用TensorFlow进行计算并返回结果。这个例子还包括了一些常见的开发框架和库,如Spring、Bootstrap、jQuery、TensorFlow.js和Universal Sentence Encoder。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值