使用CSS连接数据库

html-css035

使用CSS连接数据库,第1张

本人翻译者系奇舞团前端工程师

译文地址:https://mp.weixin.qq.com/s/dfmQUPS7_FJZ1sDK8_HS8w

原文标题:Yes, I can connect to a DB in CSS

原文作者:Memeloper

原文地址:https://www.leemeichin.com/posts/yes-i-can-connect-to-a-db-in-css.html

某公司招聘需求如下:

我们正在寻求可以 使用CSS连接数据库 的前端伙伴~

自从我上次开始一个高质量的“发帖”以来,已经有很长一段时间了,事实上,它已经很长一段时间了,那时候我的词汇表中可能还没有“水帖”这个词。

为此,我受到了一个早期项目的启发,该项目基于区块链初创公司将投资者的脸投影到3D立方体上让我想起了以前的互联网,那时一切都很奇怪。

好汉不提当年勇。所以今天,我将讨论如何管理我自己的新项目: sqlcss.xyz[1]

顾名思义,这就是使用CSS连接数据库的方式。不幸的是,它 只能在Chrome中工作 ,但你可以提供任何你喜欢的SQLite数据库,并通过CSS查询它。

它是如何工作的?

首先我们需要用到一组被亲切地称为 Houdini[2] 的api,它让你的浏览器能够通过Javascript对象模型来控制CSS。换言之,这意味着您可以定制CSS样式、添加定制属性,等等。

可能这个作品最大的特性是 CSS Paint Worklet[3] ,它允许你在一个元素上“绘制”,就像你知道和喜欢的画布一样,并让浏览器把它当作CSS中的图像。这里有一些例子可以用来 演示Houdini[4]

然而,这个工作集只提供了Worker API的一个子集,而且画布上下文本身也被大量剥离。这样做的实际结果是,您的自定义CSS绘制代码提供了一个比您预期的更小的沙盒。

这意味着什么? 没有网络访问权限,因此可以和fetch和XmlHttpRequest说再见了。在绘制上下文上没有drawText功能。其他各种JS api也消失了,以防你希望解决这些问题。

不过,不用担心。并非一切都完了。让我们把它分解成几个步骤。

这必须是第一步,以便理解概念证明是否可行。

首先我们会借助于 sql.js[5] 。它实际上是一个通过emscripten编译成WebAssembly和老式ASM.js的SQLite版本。不幸的是,我们不能使用WASM版本,因为它必须通过网络获取二进制文件。ASM版本没有这个限制,因为所有的代码都可以在一个模块中使用。

虽然PaintWorklet限制了worker内部的网络访问,但你仍然可以导入代码,只要它是一个ES6模块。这意味着文件中必须有一个导出语句。不幸的是,sql.js没有ES6的版本,所以我自己修改了sql.js,使其能够顺利的被import进入项目。

现在到了关键时刻:我可以在我的工作包中建立一个数据库吗?

**成功了!**但没有任何数据,所以我们来解决这个问题。

一开始最简单的方法就是设置一些假数据,sql.js有两个函数可以做到这一点。

我有了测试表,里面有一些值。我应该能够查询这个并获得这些值,尽管我不确定得到什么样的结构化查询结果。

正如预期的那样,结果已经出来了。不过,渲染展示通过CSS查询数据库的结果会更好。

我认为这就像在画布上写文本一样。这有多难,对吧?

不,那样就太简单了。这里的上下文与画布元素的上下文不同,它只提供了功能的一个子集。

当然,它仍然可以绘制路径和曲线,所以缺乏方便的API是一个障碍,但这一切都不是问题。

幸运的是,我们可以借助于 opentype.js[6] 所提供的解决方案。它可以解析一个字体文件,然后,给定一个文本字符串,生成每个字符的字母形式。这个操作的实际结果是一个表示字符串的路径对象,然后可以将其呈现到上下文中。

这次我不必修改opentype库来导入它,因为它已经可以从 JSPM[7] 中获得。所以,如果你给JSPM一个npm包,它会自动生成一个ES6模块,你可以直接导入到你的浏览器中。这是非常棒的,因为我真的不想为了一个有趣的项目而使用打包工具。

但这里有一个问题——它想通过网络加载字体,而我不能这样做!嗨,挫败了!

……而且?它还有一个接受数组缓冲区的解析方法。我将用base64编码字体,然后在我的模块中解码它。

我告诉过你worklet也没有处理base64字符串的api吗?atob和btoa都没有!我也不得不为此找到一个普通的JS实现。

我把这段代码放在它自己的文件中,因为它不太符合人体工程学……必须在剩下的代码旁边使用大约200kb的编码字体字符串。

这就是我为何要滥用ES模块来加载我的字体的原因。

从现在起,所有繁重的工作都由opentype库来完成,所以我所需要做的就是用一点数学知识来对齐。

最好再来一些HTML和CSS看看发生了什么。

成功了!但这里没有足够的CSS,而且查询是硬编码的。

如果必须使用CSS来查询数据库,那就更好了。事实上,这是我们可以在Paint Worker的上下文之外与其通信的唯一方式,因为没有与Web worker一样的消息传递API。

这些CSS属性被称为类型化属性,但它们本质上被封装在一个特殊的CSSProperty类中,而这个类本身并不是很有用。因此,你必须手动将其转换为字符串或数字或其他类似的使用它,如上所述。

现在对CSS做一个快速调整。

引号在这里被故意省略了,因为否则在将字符串传递给数据库之前,我必须将它们从字符串中删除。也就是说,这很有效!

任务完成!

如果你玩过sqlcss。你会注意到我并没有满足于此。在进行了一些重构之后,又进行了一些更改。

硬编码数据库模式和实际数据,有点糟糕。它证明了这个概念,但我们肯定可以做得更好。

如果您可以查询任何您喜欢的数据库,只要您手边有数据库文件,那就太棒了。我只需要读取这个文件并对其进行base64编码,就像我对字体文件所做的那样。

我为此做了一个额外的CSS属性,在这个属性中,您可以将SQLite数据库作为base64编码的数据URI提供。data URI只是为了显示并确保它对DOM是有效的,我将在Worker层面解析这些东西。

最后一步是使其更易于查询,因为否则您必须进入调试器来操作元素的CSS。

这可能是项目中最简单的部分。自定义属性对于分号有一点问题,而SQLite并不关心末尾的分号是否被省略,所以最简单的做法是,如果在输入中找到它,就删除它。

从现在开始,您可以使用CSS导入和浏览您自己的数据库了!

我遗漏了一件事,就是所有这些查询结果特别多的时候,如何更好的渲染展示的问题。如果查询结果有很多,他们需要分开到单独的行。这与本文的主题-- 使用CSS连接到数据库 并没有太大关系,所以我认为在这里谈论这个问题并不合适,但如果你想进一步了解这个"荒谬"的概念, git上的代码都是可用的[8]

[1]sqlcss.xyz: https://www.sqlcss.xyz

[2]CSS Houdini: https://developer.mozilla.org/en-US/docs/Web/Guide/Houdini

[3]CSS Paint Worklet: https://developer.mozilla.org/en-US/docs/Web/API/PaintWorklet

[4]houdini how: https://houdini.how/

[5]sql.js: https://sql.js.org/#/

[6]opentype.js: https://opentype.js.org/

[7]jspm: https://jspm.org/

[8]sqlcss git: https://git.sr.ht/~mrlee/sqlcss

如你有个和一个两个网站,分别在不同的主机上,数据库(abc.mdb)放在了的db文件夹中,那么上的conn文件连接数据库的路径这么写:db/abc.mdb,上的conn文件连接数据库的路径这么写:

这个""就是绝对路径,关于绝于与相对路径请参考下边的文章:

====================================================================

什么是绝对路径: 大家都知道,在我们平时使用计算机时要找到需要的文件就必须知道文件的位置,而表示文件的位置的方式就是路径,例如只要看到这个路径:c:/website/img/photo.jpg我们就知道photo.jpg文件是在c盘的website目录下的img子目录中。类似于这样完整的描述文件位置的路径就是绝对路径。我们不需要知道其他任何信息就可以根据绝对路径判断出文件的位置。而在网站中类似以来确定文件位置的方式也是绝对路径。 另外,在网站的应用中,通常我们使用"/"来表示根目录,/img/photo.jpg就表示photo.jpg文件在这个网站的根目录上的img目录里。但是这样使用对于初学者来说是具有风险性的,因为要知道这里所指的根目录并不是你的网站的根目录,而是你的网站所在的服务器的根目录,因此当网站的根目录与服务器根目录不同时,就会发生错误。

什么是相对路径: 让我们先来分析一下为什么会发生图片不能正常显示的情况。举一个例子,现在有一个页面index.htm,在这个页面中联接有一张图片photo.jpg。他们的绝对路径如下: c:/website/index.htm c:/website/img/photo.jpg 如果你使用绝对路径c:/website/img/photo.jpg,那么在自己的计算机上将一切正常,因为确实可以在指定的位置即c:/website/img/photo.jpg上找到photo.jpg文件,但是当你将页面上传到网站的时候就很可能会出错了,因为你的网站可能在服务器的c盘,可能在d盘,也可能在aa目录下,更可能在bb目录下,总之没有理由会有c:/website/img/photo.jpg这样一个路径。那么,在index.htm文件中要使用什么样的路径来定位photo.jpg文件呢?对,应该是用相对路径,所谓相对路径,顾名思义就是自己相对与目标位置。在上例中index.htm中联接的photo.jpg可以使用img/photo.jpg来定位文件,那么不论将这些文件放到哪里,只要他们的相对关系没有变,就不会出错。 另外我们使用“../”来表示上一级目录,“../../”表示上上级的目录,以此类推。(学习过dos的朋友可能更容易理解)

再看几个例子,注意所有例子中都是index.htm文件中联接有一张图片photo.jpg。 例: c:/website/web/index.htm c:/website/img/photo.jpg 在此例中index.htm中联接的photo.jpg应该怎样表示呢? 错误写法:img/photo.jpg 这种写法是不正确的,在此例中,对于index.htm文件来说img/photo.jpg所代表的绝对路径是:c:/website/web/img/photo.jpg,显然不符合要求。 正确写法:使用../img/photo.jpg的相对路径来定位文件

例: c:/website/web/xz/index.htm c:/website/img/images/photo.jpg 在此例中index.htm中联接的photo.jpg应该怎样表示呢? 错误写法:../img/images/photo.jpg 这种写法是不正确的,在此例中对于index.htm文件来说../img/images/photo.jpg所代表的绝对路径是:c:/website/web/img/images/photo.jpg。 正确写法:可以使用../../img/images/photo.jpg的相对路径来定位文件

例: c:/website/web/xz/index.htm c:/website/web/img/photo.jpg 在此例中index.htm中联接的photo.jpg应该怎样表示呢? 错误写法:../../img/photo.jpg 这种写法是不正确的,在此例中对于index.htm文件来说../../img/photo.jpg所代表的绝对路径是:c:/website/img/photo.jpg。 正确写法:可以使用../img/photo.jpg的相对路径来定位文件

总结:通过以上的例子可以发现,在把绝对路径转化为相对路径的时候,两个文件绝对路径中相同的部分都可以忽略,不做考虑。只要考虑他们不同之处就可以了。

如何修改样式表的路径: 使用文本编辑器打开htm文件,查看源代码,在源代码的开头部分<head>......</head>标记中间找到<link rel="stylesheet" href="test.css" type="text/css">。“Href=”后面的内容就是css的路径,我们可以根据以上的知识进行相对路径的转换。 例: c:/website/web/xz/index.htm c:/website/css/test.css 在此例中index.htm中联接test.css文件,可以使用../../css/test.css的相对路径来定位文件,完整的代码标记是:<link rel="stylesheet" href="../../css/test.css " type="text/css"> 错误写法举例:../../../css/test.css 这种写法是不正确的,在此例中对于index.htm文件来说../../../css/test.css所代表的绝对路径是:c:/css/test.css

最后,为了避免在制作网页时出现路径错误,我们可以使用dreamweaver的站点管理功能来管理站点。只要使用菜单命令site-new site新建站点并定义站点目录之后,它将自动的把绝对路径转化为相对路径,并且当你在站点中移动文件的时候,与这些文件关联的连接路径都会自动更改,实在是非常的方便。

另外,站长团上有产品团购,便宜有保证