当前位置:首页 » 网页前端 » 创建自己web框架
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

创建自己web框架

发布时间: 2023-02-12 06:14:22

1. 移动APP开发框架盘点2:Web移动前端框架大全

开源项目其实有一个成熟周期,这个周期大概是三年左右,自React框架在2013年发布并引爆了前端框架的大潮,这个属于前端的周期就此开始了。

之后在2015年5月开源的React Native又开启了属于Web移动前端的周期,15-16年,18-19年,21-22年正好就是属于移动前端的三个爆发点。

三年前,在第一个成熟收获期,我盘点了移动开发框架。在这第二个成熟收获期,理所当然要来盘点一波。

不过,当我点开github项目的code-frequency时,还是被这个准到吓人的周期猜想惊呆了,先给你们看一波,剩下的自行验证。

1、https://github.com/youzan/vant/graphs/code-frequency

2、https://github.com/quasarframework/quasar/graphs/code-frequency



再来说第二个比较有意思的发现,停止维护的项目绝大多数是Vue框架项目。

盘点开始的时候我还觉得React框架处于绝对劣势,到完成时我发现React无论在选择面还是成熟度上都超过了Vue。

原因我这里就不分析了,反正大家都有自己的看法。

网页类框架就是前端组件框架,这一次虽然有大量项目停止维护,但是也有很多项目坚持了下来,而且还涌现出了一批新项目。

大厂占了主导,因为这些年大厂在移动开发上的需求,远高于其它方面。个人项目要坚持确实不易。

本来是想要做一个验证项目,把所有框架都试用一遍并给出推荐度的。由于进度太慢,还是下一次再发吧。

这次的重点是渐进类框架,就是所谓多端同构框架(小程序框架)。这几年国内的重点的各种小程序平台,所以多端框架的需求很是旺盛。

不过大多数先行者都没挺过来还是让我很意外,只有Taro成功了,想想还是有很多让人唏嘘的东西。

在这里还是先预测一波吧,因为这一类框架最变化最大,最终还是有很多框架要出局的。

渐进类框架是一个过渡性的产品,最终会变成桥接类框架的一部分,所以,与桥接类框架协同才是框架的出路。

这个赛道基本全是大厂了。

腾讯新一代跨端开发框架Hippy

Hippy一看就是淘宝Weex的对标项目,Kpi功能全面压制。所以官方支持 React 和 Vue 两种主流前端框架。在Weex2019年实质停更后发布,要不要这么卷?

Hippy 2.x 架构主要分成三层,UI(JS) 层 Hippy-React 和 Hippy-Vue 负责驱动 UI 指令生成;中间层 C++ HippyCore 负责抹平平台差异性和提供高性能模块;渲染层 Android 和 iOS 负责提供终端底层模块、组件,并与布局引擎通信。

对Weex惨遭遗弃,我上次就说过:“ReactNative提供工具,Weex提供框架,将平台差异化屏蔽(Write Once, Run Everywhere)。所以Weex则注定功能相对弱小,并且坑比较多。”Weex最终下马也是必然的,淘宝又发布升级版北海,为了实现(Write Once, Run Everywhere),它采用自绘,而且是基于Flutter自绘。

所以Hippy3.x就一如既往的Kpi功能层层加码,很有腾讯风格。在未来的 3.x 中业务与渲染层中的具体实现可根据用户实际场景进行切换:业务层上不再局限于 JS 驱动,还可选择(如:DSL/Dart/WASM 等)其它语言进行驱动;在渲染层中,渲染引擎除了支持现有原生(Native)渲染之外,还可以选择其他渲染 Renderer,如 Flutter(Voltron) 渲染。

“Kraken 北海”是一款高性能Web渲染引擎。底层基于 Flutter 进行渲染。

Kraken 不限制上层开发者使用的框架,无论你是使用 Vue 、Rax 还是 React 都可以开发 Kraken 应用。

Kraken 的 runtime 通过 JS Engine Binding 的方式提供了一系列 Web 标准的 API 接口,调用相应 API 会执行相关逻辑并创建一系列需要发送给 Dart 层处理的指令。

Kraken 其实就是一个小程序平台,而且追求全平台完全一致。我虽然认为各平台不一致是很自然的事情,但是也表示理解,毕竟别人吹牛有当真的传统(KFC表示认同)。

Kraken 现在也是一个小号浏览器,所以它的主要工作就是抠标准,毕竟它是一款基于 W3C 标准的高性能渲染引擎。

最后,我劝淘宝领导定Kpi要理智些,毕竟Hippy4我还蛮期待的。

滴滴出品的超轻量级动态化跨端开发框架,主打轻量和实用。

Hummer 以 JS 引擎为基石,目前已支持 JavaScriptCore、Hermers、QuickJS 等业内知名 JS 引擎(这里本来还有个V8的,我删除了,源码里面没有,Kpi需要)。再配合经过调优的 Yoga 布局引擎,抹平了两端视图布局差异(性能更佳的自研布局引擎开发中)。顺便提一下,Hippy采用V8(功能更强)自研布局引擎(性能更佳)。

Hummer 的特点是抛弃了业界其他动态化跨端框架普遍使用的DSL层和VDOM层,因此原生 Hummer 不具备前端开发常用的响应式编程的能力,但同时换来的是接近原生开发的体验和性能。再以原生 Hummer 为基础,在此之上开发了一套基于MVVM架构的开发框架 —— Tenon ,通过 Tenon,可以把使用 Vue/React 编写的代码,转换成原生 Hummer 的代码。

Hummer也是一个小程序平台,而且超轻量。如果想要无限提升自己APP的能力,可以考虑嵌入Hummer。

Web移动前端框架正在迎来第三个高速发展期,各类框架得到极大繁荣。

个人在具体项目的贡献已经微乎其微了,创新、架构创新是唯一制胜的手段,这也是我看好React的根本原因。

最后,还是想做点微不足道的 探索 ,现在前端组件库层出不穷,更换组件库带来的代价有点大。想创建一个框架,来实现上次说的组件公约数和公倍数,无缝切换组件库。理论上支持所有组件库 ,也能为后来者提供弯道超车的机会。我想大厂可能没有需求,也不会愿意发布这种框架,毕竟都是平台部门说了算。

这个库就是useMobile,当然分为useMobileReact和useMobileVue。下次先发布useMobileReact。等我发布后,再来填上面表中缺的推荐度。

原文地址: https://www.cnblogs.com/windfic/p/16019457.html

2. 如何开发一个Python web框架

首先你需要知道一个Web应用基本的请求处理流程。以最简单最原始的动态网页为例,你点击链接(GET),提交表单(POST),就是与服务器端建立了连接之后发送了一个HTTP请求(RFC2616 5.1节,之后都以HTTP 1.1为例),里面至少有方法(动词,就是GET啦POST什么的,详见RFC2616第9节),地址(URL),HTTP版本,还可能带上Cookie(会话的一般实现机制),缓存相关的信息(RFC2616 13节),User-Agent串等等一堆信息。对于POST请求我们还有表单内容作为请求实体(RFC2616 7.2节),里面是你填写的表单内容。

于是我们有了一些关于请求的数据,不过现在一般来讲这些数据还在前端服务器(反向代理,比如nginx,暂且忽略掉负载均衡,反正是透明的,也不考虑裸WSGI容器直接扛请求的情况)的手上,还没有传进后端语言(这里是Python)。我们就针对每一种语言都有特定的机制,用来将HTTP的请求信息映射到相应的编程语言范畴,叫做Web服务器界面(Web server interface),通用如CGI/FCGI/SCGI,特定于某一语言如WSGI/PSGI/Rack/...,特定于某一操作系统如ISAPI(这货还活着?),一些已经不再使用的就不提了。总之在Python世界里这就是WSGI(PEP 3333, Web Server Gateway Interface),它就定义了Python语言与Web服务器之间的界面。在WSGI里,

请求的处理过程被映射为对应用callable的调用(application(environ, start_response),知乎不支持inline代码块?);
请求信息被映射到environ字典中的相应键值,比如请求方法被映射到environ['REQUEST_METHOD'],请求的“相对路径”被映射到environ['PATH_INFO'](过度简化;暂且不提WSGI应用挂载点,框架层一般也不用关心这个,挂载WSGI应用一般是WSGI容器如gunicorn、uWSGI之类组件的工作);
发送响应头的动作被映射到调用start_response(status, response_headers)(不考虑可选的第三个参数异常信息);
返回响应数据被映射到application返回iterable的动作。
于是响应便从Python返回到Web服务器,再被发送回浏览器,浏览器将响应内容渲染,一个请求就完成啦。

有了这样的感性认识,那么我们作为Python Web开发框架的作者,要做的事情就是在WSGI规范的基础之上,提供尽可能便捷的开发手段和尽可能低的框架开销,也即我们的代码将要工作在WSGI与业务逻辑的中间层。架构上,Web开发框架或多或少都遵循MVC的设计模式(Django管它叫MTV,其实差不多)。同时,由于框架位于中间件的位置,加上其鼓励模块化与代码复用的性质,自然需要为常见的HTTP操作提供抽象。这里就可以展开一些话题:
请求路径到view/controller的映射,请求参数的解析(routing,也叫路由)。
正则匹配的方案,比如Django内置了一个简单的正则表达式解析组件,能解析一般常见语法的正则表达式,把capturing groups解析成位置参数,named capturing groups解析成关键字参数。
也有DSL的方案,比如Werkzeug的路由组件。
请求实体的处理。表单解析,配合Web服务器进行上传文件处理。
正常的urlencoded表单,JSON表单,text/plain数据,multi-part表单
multi-part附件,附件操作API
大文件上传(这个一般会被前端服务器保存在磁盘上的临时文件里,比方说nginx就是这么实现的)。
会话。HTTP是无状态(stateless)的,这个特点非常重要。如果没有会话,你连续做几个请求,却没有手段证明你们是同一个人/同一台机器(你完全可能是代理服务器)。
存储会话数据的会话后端(内存数据结构?文件?RDBMS?Redis?Memcache?)
安全机制(HMAC什么的,可以参考beaker的secure cookie实现)
请求处理流程中的会话中间件(从Cookie中提取会话,从query string中提取会话,从自定义头中提取会话,等等)
View/Controller界面。发挥你的创造力,用上你的工程经验。
Function-based or Class-based views? 参考:Django, Bottle, web.py, Tornado等一票框架的做法

框架的可选机制与服务如何暴露,
装饰器?(比如@login_required 这种额外要求)
回调?(能想到的只有Tornado和Twisted这种异步框架做事情的方式,还有整个JS生态系统都是回调(不考虑Promise什么的)的思路)
传入应用(业务逻辑)层的数据结构如何设计?(HttpRequest等价物,名字可能记不清了)
响应数据结构如何设计?(HttpResponse等价物,同上)
数据库操作封装。Web应用基本都是数据为中心,这个组件非常有必要,也是撰写可复用代码必须的一环,毕竟光是框架抽象了,数据库操作还是裸sql什么的,到时候生产环境一换(比如MySQL变pgsql)还不是傻眼。
关系型数据库。一站式解决方案参考:Django ORM、SQLAlchemy;轻量级解决方案参考各数据库Python绑定。
非关系数据库。各数据库Python绑定(pymongo, riak, redis-py之类),这个没什么可替代方案了,因为本来各种NoSQL库都是适应某一特殊需求设计的,没什么互相替换的必要,那意味着重新进行技术选型。

3. 这五个Web前端开发必不可少的开源框架,闭眼入

很多Web小白在学习、在选择适合自己的Web语言时,比较纠结。其实有很多流行的、强大的前端开源框架,帮助你轻松构建漂亮的网站前端。

1、Pure

Bootstrap,Patternfly和MDC Web是功能非常强大的CSS框架,但它们可能非常繁琐和复杂。如果你想要一个轻量级的CSS框架,可以尝试Pure.css,它本身更接近于CSS编程,但又可以帮助你构建一个不错的网页。Pure是具有最小占用空间的轻量级CSS框架,它由Yahoo开发,根据BSD许可是开源的。

2、Foundation

Foundation声称是世界上最先进的响应式前端框架。它提供了用于构建专业网站的高级功能和教程。许多公司,组织都使用该框架,并且该框架具有大量可用的文档。

3、Skeleton

如果说还有什么框架比Pure更加轻量级,那一定是Skeleton。Skeleton库只有大约400行,并且该框架仅提供一些基本的CSS框架组件。尽管如此,Skeleton还是提供了详细的文档来帮助你快速上手。

4、Materialize

Materialize是一个基于Material Design风格的一个现代化的响应式前端框架,解决了最繁重的工作,结合你的自定义组件,为你提供默认的样式。Materialize的文档页面非常全面,并且很容易遵循。其组件页面包括按钮,卡片,导航等。

5、Bootstrap

Bootstrap无疑是最流行的CSS框架,它是最早的Web前端框架,由Twitter开发。Bootstrap还提供了许多示例来帮助你入门。使用Bootstrap,你可以将不同的组件和布局组合在一起,从而创建有趣的页面设计。它还提供了大量详细的文档。目前在Github上已经有1100多个贡献者,19000多个提交。

4. 用python做个简单web接口选什么框架最简单

用python做个简单web接口选什么框架最简单

不是很清楚。
只是知道用django的比较多。
以下资料供参考:
我整理的:
【整理】Python中常见的Web框架
我折腾django的:
【记录】安装Django
【记录】基于通过pip安装官网Django后,折腾第一个Django的app
【记录】基于通过pip安装官网Django后,折腾第二个Django的app

要自己写框架,首先你要知道web框架都需要哪些,你可以看一下框架原始码,或者参与到框架开源开发中。如果你要自己看原始码,推荐看bottle.py,这个python的web框架只有一个档案,很方便。如果你要参与专案,推荐django,大而全,github上的原始码很多人在做支援。如果解决了您的问题请采纳!如果未解决请继续追问!

python网站框架哪个简单

Flask 很轻,花很少的成本就能够开发一个简单的网站。非常适合初学者学习。
Flask 框架学会以后,可以考虑学习外挂的使用。例如使用 WTForm + Flask-WTForm 来验证表单资料,用 SQLAlchemy + Flask-SQLAlchemy 来对你的资料库进行控制。

荣耀6p怎么安装xp框架最简单

华为手机使用的是自身定制的安卓系统。
在安装框架的过程中可能会产生各种问题。
建议使用刷机精灵,将手机系统刷至安卓原生系统。
然后安装例如XP框架,执行更为稳定。

什么银行的网银接口最简单?

工商银行是最常用,网银接口比较简单,但是如果跨行转账汇款的话手续费比较高。招商银行的网银页面也不错。这都是日常使用过程中个人觉得比较简单好用的。

javaweb三大框架中,哪种最简单,你觉得?

Struts相对来说简单些。
因为Strusts只操作与Serlvert,不关系到别的(有些牵强,但是他对于表示式,国际化,都是在使用者体验上,也都是与Servlet打交道)。就算是Strusts2X,也是使用拦截器拦截使用者的请求,作用到servlet。
但是Spring所设计的东西和层面太多,而且都是微型的、切面的程式设计,配置档案和核心对于基础较差的还是很有难度的,尤其是初学者。
Hibernate的使用,要对资料库要相对很熟悉,尤其是资料库的理论方面,而且,Hibernate的配置需要资料的基础好,但是学好了Hibernate的话,对于程式设计有很大的好处

求个最简单易用的PHP框架,不用太多的功能,适合新手的,最简单的。

thinkphp轻量级框架,企业网站的经典运用
thinkphp是最简单的框架了,如果的的网站实在小就不用框架会更快做好,因为它也是MVC架构,而MVC就是为了方便快速开发大型网站的

5. 如何开发自己的web框架

Python 10min系列之面试题解析丨Python实现tail -f功能

发布时间:2018-02-28 来源:网络 上传者:用户

关键字:Python题解面试实现功能系列10mintail

发表文章

摘要:写这篇文章的初衷是有人去面试遇到了这个笔试题,不知道怎么做,没有什么思路,就发到了Reboot的交流群里,让大家一起讨论讨论。关于这道题,简单说一下我的想法吧。当然,也有很好用的pyinotify模块专门监听文件变化,不过我更想介绍的,是解决的思路。毕竟作为面试官,还是想看到一下解决问题的思路,而且我觉得这一题的难点不在于监控文件增量,而在于怎么打印最后面10行。希望大家在读这篇文章前,对Python基础、处理文件和常用模块有一个简单的了解,知道下面几个名词是什么:open(


代码说明:

seek第二个参数2,意思就是从文件结尾处开始seek,更标准的写法使用os模块下面的SEEK_END,可读性更好

只写出了简单的逻辑,代码简单粗暴,如果这个题目是10分的话,最多也就拿4分吧,不能再多了

优化点:

print有缺陷,每次都是新的一行,换成sys.stdout.write(line)更和谐

文件名传参,不能写死

直接打印可以当成默认行为,具体要做什么,可以写成函数处理,这样我们就可以把新行做其他处理,比如展示在浏览器里

加上容错处理,比如文件不存在会报错

while True一直都文件,比较耗性能,每读一次,间隔一秒比较靠谱

调用time.sleep(1)

用类来组织代码

实例代码如下:

# coding=utf-8
import sys
import time
class Tail():
def __init__(self,file_name,callback=sys.stdout.write):
self.file_name = file_name
self.callback = callback
def follow(self):
try:
with open(self.file_name) as f:
f.seek(0,2)
while True:
line = f.readline()
if line:
self.callback(line)
time.sleep(1)
except Exception,e:

6. 谁可以教教我如何搭建一个java web框架

1,在MyEclipse新建出来的web project就是一个web项目,
2,假如你想使用别的开源框架,你开以下载相关jar包,比如可以下载Struts,hibernate和Spring的jar包,将jar包导入到项目中,最后配置xml文件,就是SSH项目了,

7. 如何用Node去写一个Web应用框架

第一步,用node输出一个hello world

varhttp=require('http');
http.createServer(function(req,res){
varurlPares=url.parse(req.url);
varquery=querystring.parse(urlPares.query);
res.end('helloworld');
}).listen(80);


大部分的node教程在这里会告诉你,我们很容易的建立的一个服务器。但是在实际使我们通常使用的是express.(f**k,难道Node必须要用express吗?自己实现一个Web应用框架真的很难吗?)其实并不是。
那么既然打算自己写我们首先要知道我们要做哪些事情。 1.路由或者智能路由 2.静态文件输出 3.session/cookie 4.模版渲染 5.数据库处理 6.文件上传
第二步,路由
路由好高大上的名字,它是干啥的?url对应具体方法就是它该做的事情。 那么我们为什么不让url对应xxx文件的xx方法。 例如:/user/login能不能自动对应到user.js的login方法上。实现起来很难么?其实只需要几句代码

varfs=require("fs");
mole.exports=function(req,res){
varquery=req.query;
varurlPares=req.urlPares;
varpathname=urlPares.pathname;
vararr=pathname.split("/");
req.arr=arr;
//start这段代码处理默认行为。可以先忽略
if(arr.length==0||arr.length==1){
arr=["","index","index"];
}elseif(arr.length==2){
arr.push("index");
}
if(arr[1]==""){
arr[1]="index";
}
if(arr[2]==""){
arr[2]="index";
}
//end这段代码处理默认行为。可以先忽略
if(fs.existsSync(APP_PATH+'/controller/'+arr[1]+'.js')){
varcontroller=require('./controller/'+arr[1]);
if(controller[arr[2]]){
controller[arr[2]](req,res);
}else{
res.writeHead(404,{'Content-Type':'text/plain'});
res.end("你访问的控制器不存在指定方法");
}
}else{
res.writeHead(404,{'Content-Type':'text/plain'});
res.end("你访问的路径不存在");
}
}


通过fs判断文件是否存在。然后去require它就行了。APP_PATH是个全局变量表示程序入口的路径。
第三步,静态文件输出
静态文件输出我们需要一个库MIME

varurl=require("url");
varfs=require("fs");
varmime=require('mime');
/**
*[[检测是否为静态资源]]
*@param{Object}req[[Description]]
*@param{[[Type]]}res[[Description]]
*@returns{bool}[[Description]]
*/
mole.exports=function(req,res){
//正则表达式检测文件后缀
varurl_resource_reg=/.*.(html|htm|gif|jpg|jpeg|bmp|webp|htc|swf|png|ico|txt|js|css)/;
if(!url_resource_reg.test(req.url)){
returnfalse;
}
varurlPares=url.parse(req.url);
varpathname=urlPares.pathname;
varfileUrl=APP_PATH+"/static"+pathname;
if(fs.existsSync(fileUrl)){
varcontentType=mime.lookup(fileUrl);
res.setHeader('Content-Type',contentType||"text/plain");
varfileStream=fs.createReadStream(fileUrl);
fileStream.pipe(res);
fileStream.on('end',function(){
res.end();
});
returntrue;
}else{
returnfalse;
}
}
第四步,session/cookie
这里稍微有点。但是代码量也不多
varsessions={};
varsessionKey='session_key';
varEXPIRES=30*60*1000;
functionrandString(size){
varresult='';
varallChar='';
size=size||1;
while(size--){
result+=allChar.charAt(rand(0,allChar.length-1));
}
returnresult;
}
vargenerate=function(){
varsession={};
session.id=Date.now()+randString(12);
session.cookies={
expire:Date.now()+EXPIRES
}
sessions[session.id]=session;
returnsession;
}
varparseCookie=function(cookie){
varcookies={};
if(!cookie){
returncookies;
}
varlist=cookie.split(";");
for(vari=0;i<list.length;i++){
varpair=list[i].split("=");
cookies[pair[0].trim()]=pair[1];
}
returncookies;
}
varserializeCookies=function(cookies){
vararr=[];
for(varkeyincookies){
arr.push(serialize(key,cookies[key]));
}
returnarr;
}
varserialize=function(name,value,option){
varpairs=[name+'='+encodeURI(value)];
//设置cookie默认共用"/"路径
option=option||{
path:"/"
};
if(option.maxAge)pairs.push('Max-Age='+option.maxAge);
if(option.domain)pairs.push('Domain='+option.domain);
if(option.path)pairs.push('Path='+option.path);
if(option.expires)pairs.push('Expires='+option.expires);
if(option.httpOnly)pairs.push('HttpOnly');
if(option.secure)pairs.push('Secure');
returnpairs.join(';');
}
mole.exports=function(req,res){
req.cookies=parseCookie(req.headers.cookie);
varid=req.cookies[sessionKey];
if(!id){
req.session=generate();
}else{
varsession=sessions[id];
if(session){
if(session.cookies.expire>Date.now()){
session.cookies.expire=Date.now()+EXPIRES;
req.session=session;
}else{
deletesessions[id];
req.session=generate();
}
}else{
req.session=generate();
}
}
for(varkeyinsessions){
if(sessions[key].cookies.expire<Date.now()){
deletesessions[key];
}
}
varwriteHead=res.writeHead;
res.writeHead=function(){
deletereq.cookies[ham_sessionKey];
varsessionStr=serialize(ham_sessionKey,req.session.id);
res.setHeader('Set-Cookie',serializeCookies(req.cookies).concat(sessionStr));
returnwriteHead.apply(res,arguments);
}
}

第五步,模版渲染

这是最简单的。

第六步,数据库处理

这里可以是用一些ORM框架。

第七步,文件上传,post

第八步,就是你把上面的代码组织起来。

8. 如何开发一个Python web框架

  • 预备知识

    web框架主要是实现web服务器和web应用之间的交互。底层的网络协议主要有web服务器完成。譬如监听端口,填充报文等等。

  • Python内建函数__iter__和__call__和WSGI

  1. 迭代器iterator

    为类序列对象提供了类序列的接口,也就是说类序列对象可以通过迭代器像序列一样进行迭代。

  2. __call__

    在类定义的时候实现了__call__方法,那么该类的对象就是可调有的,即可以将对象当做函数来使用。

  3. WSGI

    用可调用的对象实现的:一个函数,一个方法或者一个可调用的实例。

  4. 9. 纯 Python 写一个 Web 框架,就是这么简单

    造轮子是最好的一种学习方式,本文尝试从0开始造个Python Web框架的轮子,我称它为 ToyWebF 。

    本文操作环境为:MacOS,文中涉及的命令,请根据自己的系统进行替换。

    ToyWebF的简单特性:

    下面我们来实现这些特性。

    首先,我们需要安装gunicorn,回忆一下Flask框架,该框架有内置的Web服务器,但不稳定,所以上线时通常会替换成uWSGI或gunicorn,这里不搞这个内置Web服务,直接使用gunicorn。

    我们创建新的目录与Python虚拟环境,在该虚拟环境中安装gunicorn

    在啥都没有的情况下,构建最简单的Web服务,在ToyWebF目录下,创建app.py与api.py文件,写入下面代码。

    运行 gunicorn app:app 访问 http://127.0.0.1:8000 ,可以看见 Hello, World! ,但现在请求体中的参数在environ变量中,难以解析,我们返回的response也是bytes形式。

    我们可以使用webob库,将environ中的数据转为Request对象,将需要返回的数据转为Response对象,处理起来更加直观方便,直接通过pip安装一下。

    然后修改一下API类的 __call__方法 ,代码如下。

    上述代码中,通过webob库的Request类将environ对象(请求的环境信息)转为容易处理的request,随后调用handle_request方法对request进行处理,处理的结果,通过response对象返回。

    handle_request方法在ToyWebF中非常重要,它会匹配出某个路由对应的处理方法,然后调用该方法处理请求并将处理的结果返回,在解析handle_request前,需要先讨论路由注册实现,代码如下。

    其实就是将路由和方法存到self.routes字典中,可以通过route装饰器的形式将路由和方法关联,也可以通过add_route方法关联,在app.py中使用一下。

    因为url中可以存在变量,如 @app.route("/hello/{name}") ,所以在匹配时,需要进行解析,可以使用正则匹配的方式进行匹配,parse这个第三方库已经帮我们实现了相应的正则匹配逻辑,pip安装使用一下则可。

    这里定义find_handler方法来实现对self.routes的遍历。

    了解了路由与方法关联的原理后,就可以实现handle_request方法,该方法主要的路径就是根据路由调度对应的方法,代码如下。

    在该方法中,首先实例化webob库的Response对象,然后通过self.find_handler方法获取此次请求路由对应的方法和对应的参数,比如。

    它将返回hello方法对象和name参数,如果是 /hello/二两 ,那么name就是二两。

    因为route装饰器可能装饰器的类对象,比如。

    此时self.find_handler方法返回的hanler就是个类,但我们希望调用的是类中的get、post、delete等方法,所以需要一个简单的判断逻辑,通过inspect.isclass方法判断handler如果是类对象,那么就通过getattr方法获取类对象实例的中对应的请求方法。

    如果类对象中没有该方法属性,则抛出该请求类型不被允许的错误,如果不是类对象或类对象中存在该方法属性,则直接调用则可。

    此外,如果方法的路由并没有注册到self.routes中,即404的情况,定义了defalut_response方法返回其中内容,代码如下。

    如果handle_request方法中调度的过程出现问题,则直接raise将错误抛出。

    至此,一个最简单的web服务就编写完成了。

    回顾Flask,Flask可以支持HTML、CSS、JavaScript等静态文件,利用模板语言,可以构建出简单但美观的Web应用,我们让TopWebF也支持这一功能,最终实现图中的网站,完美兼容静态文件。

    Flask使用了jinja2作为其html模板引擎,ToyWebF同样使用jinja2,jinja2其实实现一种简单的DSL(领域内语言),让我们可以在HTML中通过特殊的语法改变HTML的结构,该项目非常值得研究学习。

    首先 pip install jinja2 ,然后就可以使用它了,在ToyWebF项目目录中创建templates目录,以该目录作为默认的HTML文件根目录,代码如下。

    首先利用jinja2的FileSystemLoader类将file system中的某个文件夹作为loader,然后初始化Environment。

    在使用的过程中(即调用template方法),通过get_template方法获得具体的某个模板并通过render方法将对应的内容传递给模板中的变量。

    这里我们不写前端代码,直接去互联网中下载模板,这里下载了Bootstrap提供的免费模板,可以自行去 https://startbootstrap.com/themes/freelancer/ 下载,下载完后,你会获得index.html以及对应的css、jss、img等文件,将index.html移动到ToyWebF/templates中并简单修改了一下,添加一些变量。

    然后在app.py文件中为index.html定义路由以及需要的参数。

    至此html文件的支持就完成了,但此时的html无法正常载入css和js,导致页面布局非常丑陋且交互无法使用。

    接着就让ToyWebF支持css、js,首先在ToyWebF目录下创建static文件夹用于存放css、js或img等静态文件,随后直接将前面下载的模板,其中的静态文件复制到static中则可。

    通过whitenoise第三方库,可以通过简单的几行代码让web框架支持css和js,不需要依赖nginx等服务,首先 pip install whitenoise ,随后修改API类的 __init__ 方法,代码如下。

    其实就是通过WhiteNoise将self.wsgi_app方法包裹起来,在调用API的 __call__ 方法时,直接调用self.whitenoise。

    此时,如果请求web服务获取css、js等静态资源,WhiteNoise会获取其内容并返回给client,它在背后会匹配静态资源在系统中对应的文件并将其读取返回。

    至此,一开始的网页效果就实现好了。

    web服务如果出现500时,默认会返回 internal server error ,这显得比较丑,为了让框架使用者可以自定义500时返回的错误,需要添加一些代码。

    首先API初始化时,初始self.exception_handler对象并定义对应的方法添加自定义的错误

    在handler_request方法进行请求调度时,调度的方法执行逻辑时报500,此时不再默认将错误抛出,而是先判断是否有自定义错误处理。

    在app.py中,自定义错误返回方法,如下。

    custom_exception_handler方法只返回自定义的一段话,你完全可以替换成美观的template。

    我们可以实验性定义一个路由来看效果。

    Web服务的中间件也可以理解成钩子,即在请求前可以对请求做一些处理或者返回Response前对Response做一下处理。

    为了支持中间件,在TopWebF目录下创建middleware.py文件,在编写代码前,思考一下如何实现?

    回顾一下现在请求的调度逻辑。

    1.通过routes装饰器关联路由和方法 2.通过API.whitenoise处理 3.如果是请求API接口,那么会将参数传递给API.wsgi_app 4.API.wsgi_app最终会调用API.handle_request方法获取路由对应的方法并调用该方法执行相应的逻辑

    如果希望在request前以及response后做相应的操作,那么其实就需要让逻辑在API.handle_request前后执行,看一下代码。

    其中add方法会实例化Middleware对象,该对象会将当前的API类实例包裹起来。

    Middleware.handle_request方法其实就是在self.app.handle_request前调用self.process_request方法处理request前的数据以及调用self.process_response处理response后的数据,而核心的调度逻辑,依旧交由API.handle_request方法进行处理。

    这里的代码可能会让人感到疑惑, __call__ 方法和handle_request方法中都有self.app.handle_request(request),但其调用对象似乎不同?这个问题暂时放一下,先继续完善代码,然后再回来解释。

    接着在api.py中为API创建middleware属性以及添加新中间件的方法。

    随后,在app.py中,自定义一个简单的中间件,然后调用add_middleware方法将其添加。

    定义好中间件后,在请求调度时,就需要使用中间件,为了兼容静态文件的情况,需要对css、js、ing文件的请求路径做一下兼容,在其路径中加上/static前缀

    紧接着,修改API的 __call__ ,兼容中间件和静态文件,代码如下。

    至此,中间件的逻辑就完成了。

    但代码中依旧有疑惑,Middleware类中的 __call__ 方法和handle_request方法其调用的self.app到底是谁?

    为了方便理解,这里一步步拆解。

    如果没有添加新的中间件,那么请求的调度逻辑如下。

    在没有添加中间件的情况下,self.app其实就是API本身,所以 middleware.__call__ 中的self.app.handle_request就是调用API.handle_request。

    如果添加了新的中间件,如上述代码中添加了名为SimpleCustomMiddleware的中间件,此时的请求调度逻辑如下。

    因为注册中间件时,Middleware.add方法替换了原始Middleware实例中的app对象,将其替换成了SimpleCustomMiddleware,而SimpleCustomMiddleware也有app对象,SimpleCustomMiddleware中的app对象,才是API类实例。

    在请求调度的过程中,就会触发Middleware类的handle_request方法,该方法就会执行中间件相应的逻辑去处理request和response中的数据。

    当然,你可以通过Middleware.add方法添加多个中间件,这就会构成栈式调用的效果,代码如下。

    启动web服务后,其执行效果如下。

    10. web前端开发框架有哪些

    常见的web前端开发框架如下:

    1、Bootstrap:

    主流框架之一,Bootstrap 是基于 HTML、CSS、JavaScript的,它简洁灵活,使得 Web 开发更加快捷。

    2、html5-boilerplate:

    该框架可以快速构建健壮,且适应力强的web app或网站。

    3、Meteor:

    Meteor是新一代的开发即时web应用的开源框架,它能在较短时间内完成开发。

    4、Materialize:

    基于材料设计的现代化响应式前端框架。可提供默认的样式,自定义组件。此外,Materialize还改进动画和过渡,为开发人员提供流畅的体验。

    5、Amaze UI:

    国内首个开源HTML5跨屏前端框架产品系列,中文排版支持更优、本土化组件丰富。该产品系列中有专门针对移动端的HTML5混合应用开发框架Amaze UI Touch以及针对跨屏HTML5网页开发的Amaze UI Web。

    (10)创建自己web框架扩展阅读:

    web框架程序的作用:

    Web框架使得在进行Web应用开发的时候,减少了工作量。Web框架主要用于动态网络开发,动态网络主要是指现在的主要的页面,可以实现数据的交互和业务功能的完善。

    使用Web框架进行Web开发的时候,在进行数据缓存、数据库访问、数据安全校验等方面,不需要自己再重新实现,而是将业务逻辑相关的代码写入框架就可以。也就是说,通过对Web框架进行主观上的“缝缝补补”,就可以实现自己进行Web开发的需求了。

    以PHP为例,PHP可以在apache服务器上进行Web开发,而不必使用框架。使用PHP进行开的时候,在不适用框架的情况下,数据库连接就需要自己来实现,页面的生成和显示也是一样。比如框架的话可以完成避免sql注入的工作,而使用PHP在不用框架的情况下,这部分要自己做。

    参考资料来源:网络-前端开发