与之前静态页面相关的内容不同,要实现 用户登录,必然涉及到 数据的交互。
在所有开始之前,我们需要了解下,一般前端与后端之间是如何实现数据的交互的。在 HTML 层面上,如果不引入 Javascript,要实现前后端的关联,会使用 FORM
这个 DOM 元素,然后在 FORM 内填充数据的字段元素。
FORM 以中文的术语是 表单
,关于表单设计
,还可以引出几本砖头大的书,但于我们没有什么必要,它可以是非常专业的(保持敬畏),也可以不专业(别被吓到),只要 表达
到位即可。
注: 前端
主要指基于用户使用的浏览器端的技术,而后端
主要指由程序员控制、实现的服务(器)端的相关技术。
FORM 其实跟 HTML 常用的 DOM 元素 DIV 差不多,只是类型不同,浏览器赋予它的默认表现、交互行为不同而已,在涉及到表单 (需要用户填表、提交数据用的),一般是元素 FORM (相当于一个大容器)包含多个 INPUT 字段,从而构建整个表单。
form#form_one(action="", method="POST")
div.form_field.username
label Username
input(type="text", name="username", placeholder="hepo")
div.form_field.password
label Password
input(type="password", name="password", placeholder="123456")
div.form_field.submit
input(type="submit", value="登录")
简单说下代码中的一些含义:
form#form_one(action="", method="POST")
,一般会给 FORM 以一个 id,比如这里的 form_one
,因为多数时候需要对 FORM 进行操作,有 id 则方便识别、调用、控制。action
表示数据往哪个 URL 提交,如果没有指定或为空,表示往当前页面的 URL 提交;method
是提交数据的方式,一般是 POST
。
div.form_field.username
label Username
input(type="text", name="username", placeholder="hepo")
这段代码,使用了之前介绍的常见布局方法,先外部包裹有一个 DIV,form_field
是一个通用的 class,username
是当前这个 field 特殊指定的。label
一般在 FORM 内配合 INPUT 使用,label 有一个特殊的属性 for
,你可以在源代码中尝试修改为 label(for="username") Username
, 然后给后面 username 一个 id=username
的属性;这时,界面上点击 label 中的文本,光标会自动 focus 到 INPUT 这个元素之中。
重点需要说明的是 INPUT
,它有多个 type
,比如 text、password、radio、checkbox、submit、hidden(隐藏的元素,但可以有 value 以便在提交时一并传给服务器),不同 type 在视觉、交互表现上也不一样。
INPUT
除了 type 之外,其它一些非常重要的属性:
name
,则服务端上获得对应的数据会超级不方便;一般情况下,当前 FORM 内 name 最好是唯一的,不要重复。
字段
的 DOM 元素,则建议设定。
我们在最开始的时候,介绍如何使用 Jade 代替 HTML,包括之前处理静态页面的时候,也基本上使用了 Jade 的代码来写。
接下来,因为动态页面,会很自然地引入 变量
这个概念,需要此时对 Jade 的基本语法重新捋一遍,建议可以翻回到前面再看一看。
本段落,主要针对 Demo 中源码片段,做逐行的解释,以增加大家的理解。
if request.method == 'POST' --> 逻辑判断
h2 来自浏览器的数据交互: -->
p --> P 标签
span Method: --> SPAN 标签 + 普通文本
b= request.method --> B 标签(加粗效果) + 变量(=后面多个空格)
p --> P 标签
span Data: --> SPAN 标签 + 普通文本
pre= request.values.to_dict().json --> PRE 标签 + 变量(=后面多个空格)
像 request.method
和 request.values.to_dict().json
,这些变量都不是天然形成的,而是 FirstWeb 的基本 Web 引擎 farbox_lite 带来的,所以我们并不需要特别记住这些变量以及属性,因为它们的适用性仅限于 FirstWeb 中。以 request
为例,它是当前浏览器 请求
所包含的各种信息,我们将其统一归纳到一个变量对象
,名为 request
;而 request.form
表示是 POST
这个 method
时浏览器传入的各种值,request.args
则针对 GET
,request.values
是 POST+GET
的合集。
像 request.values.to_dict().json
它翻译成人类的语言,大抵是: 先取 request 上的一个叫 values 的属性(得到了一个变量),调用其另外一个属性 to_dict
,这个属性是一个函数(用()
结尾表示无参数时的函数运行),获得变量之后,再获取其 json
这个属性(作用是转为 JSON 格式的字符串)。
在介绍 INPUT 的时候,说它是有不同 type 的,比如 submit
这个类型,表现行为相当于是一个按钮,点击『按钮』的时候,就会提交表单内的数据了;没有 submit
,默认就没有办法提交数据了。
多数时候,有 FORM 的地方,就有 Javascript,与此同时,因为 Javascript 的介入, 我们可以将 submit
的行为,移到其它 DOM 元素上。此时, A 元素(超链接) 是非常天然的替代元素。
在 Demo 的页面中,我们也做了这个演示:
document.getElementById('form_two').submit(); // 原生 Javascript 提交
$('#form_two').submit(); //由 jQuery 提交
FirstWeb 的框架源自于 Bitcron,有些 API 的调用方式 (如 Jade 模板的特定的语法、默认的变量) 也尽可能保持兼容,主要是 d (data)
与 html (h)
这两个变量空间 (此处空间
其实就是一个大的变量集合,可供内部调用子属性
、子函数
)。具体参考 https://api.bitcron.com/read/d 以及 https://api.bitcron.com/read/h。
在后续的 Demo 的源码中,我们会看到如下 h.load
的函数调用,它可以同时载入 .js
、.css
,但也仅是 FirstWeb 中动态框架 ( template 目录下的文件)中生效。其本质而言,不过是 技术在不断弥合人类的懒惰,因为,就不用特别去记忆了 js、css 分别如何载入的 HTML 语法了。
+h.load('/template/script.js')
+h.load('/template/style.css')
<script type="text/javascript" src="/template/frontend/script.js"></script>
<link href="/template/frontend/style.css" type="text/css" rel="stylesheet"/>
好了,我们继续去实现『如何实现账户的登录』……