网站请求处理
【E2EE文档】

网站请求处理

[服务器请求] 对象是网站请求处理的核心对象。通过它我们可以获取浏览器提交的参数,用户上传的文件和用户的Cookie等信息。

在以下内容中,将使用别名“请求”来表示[服务器请求]。[请求]对象只能在[视图函数]中使用。

 

获取浏览器提交的参数

获取参数的基本方法

获取提交参数的基本方法主要有三个:

  • 请求.取参数
  • 请求.取多值参数
  • 请求.取所有参数

在大部分场景中,我们只需要通过[请求.取参数]方法,就能快速获取到各种来源的参数内容。

1. 取参数

通过名称获取参数,当参数为[多值参数]时,将返回最后一个参数的内容。

2. 取多值参数

请求中如果同一个名称的参数有多个内容时,我们称之为[多值参数]。例如:

http://127.0.0.1:8080/user/delete?id=1&id=5&id=7

其中名称为“id”的参数,拥有多个值。此时我们可以通过[请求.取多值参数]获取其每一项结果:

数组{1, 5, 7}

3. 取所有参数

获取所有请求接收和处理的参数内容。返回数据为[存取键值表]对象。

注意

[取所有参数]返回的[存取键值表],不同于普通的键值表,其生命周期将贯穿本次请求始终。

如果您在[全局函数]中修改了这个[键值表]的值,在接下来的[视图函数]中再次调用[取所有参数]时,得到的将是修改后的内容。

要避免它的内容被改变,您可以通过[键值表.合并到]方法,将参数键值表的数据直接拷贝合并到局部变量中的[键值表]对象中。

 

参数的数据来源

通过[取参数]方法可以获取以下来源的参数内容:

  • 请求参数 (QueryString: 网址尾部携带的参数)
  • 路由参数 (订阅时的网址变量)
  • 提交参数 (POST/PUT 提交的参数)

这几种参数来源,在同一个请求中,可以同时使用。

 

获取[请求参数]

浏览器发起请求时,可以通过在网址尾部携带[请求参数(QueryString)]的方式,提交数据给网站。例如以下的网址:

https://www.baidu.com/s?wd=E2EE&from=mobile

其中“wd”和“from”就是[请求参数],内容为要查询的数据“E2EE”和来源内容“mobile”。

我们在[视图函数]中,可以通过以下方式直接获取到结果。

E2EE

[请求参数]格式

  • 在网址尾部以“?”开头

    • 只允许使用一次“?”
  • 名称和内容之间通过“=”进行分割

    • 只有名称没有内容时可以带和不带“=”都行,参数都将存在但是内容为空文本(可以通过[是否存在参数]方法判断)
  • 多个参数之间通过“&”进行分割

  • 名称或内容不为ASCII的时候必须进行[URL编码]操作

    • [注意] 进行[URL编码]操作时除非编码格式跟服务器一致否则必须在HTTP协议头部的“Content-Type”中通过“charset”指定数据的编码类型

以下为正确的[请求参数]格式

/user/detail?id=5

/user/detail?id=5&id=3

/echo?name=JimStone&sex=%E7%94%B7%E5%AD%A9&age=18

以下为错误的[请求参数]格式

/user/detail&id=5 必须以“?”开始

/user/detail?id=5?id=3 多个参数之间必须用“&”进行分割且“?”也只能使用一次

/echo?name=JimStone&sex=男孩&age=18 非ASCII没有进行[URL编码]操作(浏览器通常会自动编码)

示例

E2EE

mobile

注意

[请求参数]中的内容不建议过长,因为通常服务器会限制网址的长度,如果网址过长可能会造成请求失败,通常建议网址的内容控制在1024字节以内。过长的内容建议改用POST/PUT等[提交参数]的方式进行提交。

 

获取[路由参数]

在[网站服务器]对象中,使用[订阅视图函数]订阅路由网址的时候,在路由网址中加入的变量,我们称为[路由参数]。

例如:

其中“id”就是我们[路由参数]的名称。当浏览器输入以下网址时:

/user/detail/1211

我们在[视图函数]“提交参数视图路由参数”中,可以直接通过[取参数]获取到内容:

1211

示例

1211

 

获取[提交参数]

在网页中,设置表单(form)的请求类型(method)为“POST”或“PUT”类型时,所有提交的参数都叫做[提交参数]。通常用于文件上传、多参数 和 大尺寸参数数据的内容提交。

示例

JimStone

18

要理解[提交参数]需要先理解下[HTTP请求头]中的“Content-Type”。

什么是“Content-Type”?

在请求中,Content-Type请求头会告诉服务器,实际提交内容的内容类型。

Content-Type包含3部分:

  • media-type 资源或数据的 MIME type
  • charset 字符编码标准。
  • boundary 对于包含多个部分的提交内容,boundary 是必需的,其包括来自一组1到70个字节长度的字符串。用来作为多个内容之间的分割符。

Chrome等浏览器中提交表单时,通常会自动指定“charset”为“UTF-8”。E2EE允许客户端通过自己的编码格式来提交数据,而在非浏览器环境中执行“POST/PUT”请求时,请务必设置“charset”或者将内容转换为和网站一致的编码格式,否则服务器接收到的数据可能会转码失败导致数据出错。

典型的定义:

Content-Type: application/x-www-form-urlencoded; charset=utf-8

网站服务器支持的“media-type”类型:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • application/json
  • text/xml

不同类型的内容实际处理方式也将完全不同。在E2EE中,不需要过于关注这些类型,因为我们都可以通过 [请求.取参数] 或 [请求.取所有参数] 获取。

application/x-www-form-urlencoded

提交的数据需要进行[URL编码]处理(浏览器会自动处理),格式跟上文中提到的[请求参数]格式完全一致。

multipart/form-data

多值的参数,常用于文件上传操作。使用时必须要指定“boundary”(浏览器会自动处理)用来作为值之间的分隔符。使用[网站客户端]上传文件时,也不需要手动处理,客户端会自动处理这部分信息。

application/json

JSON类型的内容。当识别到这种格式时,服务器对象会自动将JSON内容解析为[存取键值表](必须是以“{}”包裹的JSON内容否则无法处理)。通过[取所有参数]可以直接获取解析后的内容。如果是Array类型的JSON(以“[]”包裹的内容),您可以使用[请求.取原始请求数据]方法获取内容,手动调用[存取列表.从JSON载入]方法加载内容。

text/xml

XML类型的内容。目前服务器并不会自动解析XML内容,您可以使用[请求.取原始请求数据]方法获取内容,配合[网页内容解析器]对象进行XML结果的提取。

注意

如果使用[网站客户端]对象,请务必使用[网站客户端.置编码]设置编码格式,或者保持数据编码和服务器设置一致。

服务器只接收指定了“Content-Length”请求头的[提交参数]。如果您在非浏览器环境中,使用的不是[网站客户端]对象时,如果请求失败,请检查“Content-Length”请求头是否正常。

 

获取参数的辅助方法

辅助获取提交参数的方法:

  • 请求.是否存在参数
  • 请求.上传文件_XXX
  • 请求.取原始提交数据

是否存在参数

用来判断某个名称的参数是否存在。可以通过指定[是否判断值]参数,来指定空值时参数算不算为[存在]状态。

上传文件_XXX

获取上传文件和上传文件相关的信息。在后边的上传文件部分会有详细介绍。

取原始提交数据

当网站默认的请求参数处理和获取方式,无法满足您的需求时,可以使用[请求.取原始提交数据]方法获取原始提交数据内容。

[注意] 内容类型为“multipart/form-data”时,您是无法通过此方法获取原始数据的,只能通过 [请求.取参数] 或 [请求.取所有参数] 方法获取参数结果。

 

获取请求相关信息

HTTP请求消息实际包含三部分内容:

  • 请求行
  • 请求头
  • 请求数据(允许为空)

以下是一个典型的GET请求消息:

HTTP请求消息中首行为[请求行]。

GET /index.html HTTP/1.1

其中:

[请求类型] GET

[请求路径] /index.html

[协议版本] HTTP/1.1

第二行开始,均为[请求头]信息。

 

获取[请求行]信息方法

取请求类型

  • 请求.取请求类型

获取当前请求的类型,HTTP1.1协议中支持的方法类型:

  • GET
  • POST
  • HEAD
  • PUT
  • DELETE
  • TRACE
  • CONNECT
  • OPTIONS

GET

 

取请求路径

  • 请求.取请求路径

取请求的相对路径。

/index.html

 

取请求版本号

  • 请求.取请求版本号

获取用户请求版本号信息。本方法返回[协议版本]“HTTP/”后的内容。目前支持“1.0”和“1.1”。

1.1

 

获取[请求头]方法

取请求头

取回指定名称的请求头:

  • 请求.取请求头

e2ee.jimstone.com.cn

 

取所有请求头

取回所有请求头:

  • 请求.取所有请求头
  • 请求.取所有请求头_到参数

当同一个名称的请求头有多个时,只保留最后一个。

 

取原始请求头

返回请求部分的原始内容:

  • 请求.取原始请求头

 

获取其它请求信息

取客户端IP和端口

获取用户客户端地址(IP) 和 端口 的方法:

  • 请求.取用户地址
  • 请求.取用户端口

代理环境下的使用

在使用Nginx等代理方式访问网站时,您需要在代理中配置“X-real-ip”或者“X-Forward-For”请求头,将原用户地址写入到对应的请求头中。而在网站配置中,您需要在[真实IP请求头]配置项填入代理中配置的请求头名称。

 

判断用户是否为手机

判断当前请求是否为手机用户的方法:

  • 请求.是否手机用户

判断机制

  • 判断是否存在“X-Wap-Profile”请求头,存在则为手机用户。

  • 判断请求头“User-Agent”是否能匹配手机用户的关键字表达式。

    • 该表达式来自网站配置项“手机UA表达式”,如果需要修改表达式,可以使用[E2EE控制中心]对此配置项进行设置。

 

Cookie和Session

Cookie

Cookie是HTTP会话中,通过浏览器保存用户信息的一种方式。

Cookie是明文公开的,正常环境下不适合存储任何私密信息。Cookie有被篡改的风险,如果您需要存储当前用户信息,并且不想被浏览器查看到或恶意串改,请使用Session。

Cookie的存储周期是可以手动指定的,且开启多个浏览器窗口时,Cookie是共享的。在指定Cookie存储周期时,关闭和重启浏览器,不会对Cookie存储的数据产生影响,通常下次启动后会继续沿用之前的Cookie数据。

获取Cookie

  • 请求.取Cookies

本方法会返回存储有当前用户Cookies的[存取键值表]对象。其中[主键]为Cookie的名称,[值]为Cookie内容。

当同名称同路径下的Cookie有多个值的时候(通常浏览器不会发送同名多值Cookie),只会保留最后一个Cookie内容。

 

Session

Session是在HTTP会话中,将用户信息保留在服务端的一种方式。默认情况下,用户关闭浏览器后,Session会被自动清空。

Session常用于存储用户登录状态、权限和操作流程状态等信息。

Session是基于Cookie机制实现的。当设置Cookie时,不指定存储周期时,Cookie内容只会保留在内存中。当浏览器关闭后,对应的Cookie将不再存在。Session就是基于这个特性,通过生成一段随机内容的[ID],将其存储在Cookie中做为读写数据的钥匙,从而实现在服务端保存用户会话数据的。

 

获取Session的ID

  • 请求.取SessionID

获取用户的Session的ID。这段ID是服务器随机生成的,通过随机算法和命中判断,保证生成后[ID]的唯一性(不存在生成重复ID的可能)。

 

获取和设置Session

设置Session

  • 请求.置Session值

通过[主键]名称设置Session内容文本。主键名称可以为任意文本。如果不指定[值文本]参数,将删除[主键]对应的Session值。

获取Session

  • 请求.取Session值

返回[主键]名称获取Session内容文本。主键不存在返回[空]文本。

清空Session

  • 请求.清空Session值

清空当前用户的所有Session值内容。

 

过期时间

您可以在 [E2EE控制中心] > [配置] > [Session设置] 中指定Session的过期时间。

过期时间自动续期

在满足以下任意条件时会触发Session自动续期操作:

  • 调用 [请求.置Session值] 方法
  • 在上次续期超过2分钟后,访问过调用了 [请求.取Session置] 方法的[视图函数]

自动续期操作会重置Session的过期时间,为网站配置项[SESSION时间]指定时间周期。

 

文件上传

上传文件是网站中常用的功能,在E2EE中针对上传的文件的大致处理流程如下:

  1. 网站接收文件到 [临时目录]
  2. 使用时在[视图函数]中[移动文件]到[网页目录]下
  3. 请求结束后如果文件未“移动”那么将被自动删除

上传通常可以使用 [网站.移动文件],将上传后的临时文件移动到网站相关的目录中。

示例

 

获取上传文件信息

获取文件路径

  • 请求.上传文件_取上传文件路径

通过表单名,获取用户上传后的文件的绝对路径(通常在[临时目录]下)。如果要使用该文件请移动到需要的地方,未移动的文件在请求处理完成后将自动删除。

获取文件信息

  • 请求.上传文件_取上传文件信息

通过表单名获取上传文件信息。数据将被写入到[文件信息]参数指定的[存取键值表]变量中,[键值表]的主键可以使用“#上传主键_”常量获取对应内容。

获取所有的上传文件信息

  • 请求.上传文件_取所有上传文件

取所有上传的文件信息列表。返回文件列表的数量。文件信息会被写入[上传文件列表]参数指定的[存取列表]对象中。[存取列表]内的每一项都为[存取键值表]类型,其主键可以使用“#上传主键_”常量,获取对应上传文件详细信息。

 

上传流程控制

订阅上传全局函数

可以通过订阅全局函数的方式,在文件上传开始时控制上传流程:

  • 网站.订阅全局函数 (&全局_开始上传, #全局函数_上传文件)

当文件上传失败时,也可以通过订阅全局函数来获取失败时的信息:

  • 网站.订阅全局函数 (&全局_上传失败, #全局函数_上传失败)

在[全局函数_上传文件]函数中控制流程

  • 请求.上传文件_取当前文件信息
  • 请求.上传文件_置当前文件路径
  • 请求.上传文件_跳过当前文件
  • 请求.上传文件_终止文件上传
  • ==== [正在上传] ==== 文件路径: C:/示例代码/临时/9084_10475.jpg 文件名: QQ图片20181026165329.jpg 表单名: img 文件尺寸: 0 上传状态: 0
  • [输出路径] C:/示例代码/uploads/9084_10475.jpg

 

上传文件信息常量

当使用[请求.上传文件_取上传文件信息]或[请求.上传文件_取所有上传文件]时,在文件信息的[存取键值表]中,可以通过以下常量做为[主键]获取上传文件的信息:

  • #上传主键_状态

    • 上传文件的状态。逻辑型。上传成功则值为“真”
  • #上传主键_代码

    • 上传文件的代码。整数型。可使用“#上传代码_”常量进行比较。[0] 成功 [1] 未启用上传 [2] 超出最大上传尺寸 [3] 不允许的上传类型
  • #上传主键_表单名称

    • 上传文件的原始表单名称()。文本型
  • #上传主键_原文件名

    • 上传文件的原始名称。文本型。只包含文件原始名称不包含原始路径
  • #上传主键_上传路径

    • 文件上传后的路径。文本型。通常在“临时”目录中。如果要使用请通过 服务器.移动文件 将上传文件移动到需要的位置,如果未对文件进行处理,则在请求处理完后文件将自动删除
  • #上传主键_错误原因

    • 上传失败的具体错误原因。文本型。只有上传失败时才存在此值

其中通过[主键]为“#上传主键_代码”常量时,对应的值,可以通过和以下常量做比较获取具体原因:

  • #上传代码_成功

    • 未知原因造成的上传失败。可能由于写入失败等造成
  • #上传代码_未开启上传

    • 服务器未开启上传
  • #上传代码_文件尺寸过大

    • 超出文件最大上传尺寸限制
  • #上传代码_不允许的类型

    • 不允许的上传文件类型
  • #上传代码_无法写入文件

    • 写入上传文件失败
  • #上传代码_无上传文件

    • 没有任何上传文件
  • #上传代码_上传被取消

    • 文件上传被取消

 

属性表:穿梭于『全局』和『视图』间的信使

在 [全局函数]、[视图函数] 到 [后置全局函数] 之间,经常需要进行数据的传递。可以通过以下方法进行数据传递:

  • 请求.属性表

[属性表] 是一种特殊的 [存取键值表],在同一次的请求处理过程中,无论是 [全局函数]、[视图函数] 还是 [后置全局函数],通过 [请求.属性表] 得到的都是同一个键值表。

您可以通过对 [属性表] 的读取和赋值操作,在各个流程之间传递数据。

注意

[属性表] 在任何环境下,都将自动用做模板渲染时的[模板数据]。所以您可以通过写入数据到[属性表],直接输出要渲染的数据到最终模板中。

示例

E2EE是最棒的

 

函数标签:『视图』函数拦截过滤器

[函数标签] 是网站流程处理的拦截过滤器。当 [视图函数] 和 [全局函数] 拥有相同的[标签]时,在执行视图前,会优先调用[全局函数]

函数标签的适用场景:

  • 用户验证
  • 权限系统
  • 数据注入
  • 分组处理

示例

标签信息处理

获取标签列表

  • 请求.取标签列表

获取[视图函数]绑定的标签列表。返回的列表为只读,请不要做添加删除等操作。如果需要修改使用此列表,请使用复制方法。

判断标签是否存在

  • 请求.是否包含标签

判断视图函数是否绑定了指定名称的标签。

 

远程服务

在 [控制中心] 中使用 [定义远程服务] 工具,可以配置远程服务功能。

相关方法

  • 请求.远程服务_取所有参数
  • 请求.远程服务_取参数到变量

 

验证器

在 [控制中心] 中,可以使用 [视图表单验证器] 或者 [远程服务验证器]工具,对路由地址进行参数验证规则的设置。

相关方法

  • 请求.验证参数
  • 请求.验证所有参数

 

容器化

做为 [容器化] 的 [模块] 使用时,可以使用以下方法获取模块路径:

  • 请求.取模块路径

取服务器在容器中的相对路径,尾部不包含“/”。当在[主服务器]中使用时,返回空文本。

 

数据库

请求对象提供了数据库操作的快捷方法,可以使用 “请求.数据库_” 开头的方法,作用等同于把 [请求]对象 当 [数据库连接]对象 使用。

要使用数据库快捷方法,请确保您在网站初始化时,执行过 [数据库连接池.创建] 方法,并成功绑定到了您的 [网站]对象 中。

当您的 [网站]对象 还没有跟 [数据库连接池]对象 进行绑定时,所有的“请求.数据库_”快捷方法都将返回失败。

相关方法:

  • 请求.数据库_取连接
  • 请求.数据库_查询
  • 请求.数据库_查询到自定义数组
  • 请求.数据库_查询_到属性表
  • 请求.数据库_查询头条
  • 请求.数据库_查询头条到自定义
  • 请求.数据库_查询头条_到属性表
  • 请求.数据库_查询到分页
  • 请求.数据库_执行
  • 请求.数据库_保存对象
  • 请求.数据库保存对象键值参数
  • 请求.数据库_取回错误

详细使用方法可以查看[数据库]文档。

注意

请求中的数据库方法组并不适用于需要使用“事务”的场景,如果您需要用到“事务”特性,请使用 [请求.数据库_取连接] 取回连接后,通过[数据库连接]对象进行数据库事务处理。

 

对象映射

请求对象提供了对象映射功能的快捷方法,可以使用 “请求.对象映射_” 开头的方法,作用等同于把 [请求]对象 当 [对象映射中心]对象 使用。

使用前请确保您已经配置好了[对象映射]相关的信息。

相关方法:

  • 请求.对象映射_对象转自定义
  • 请求.对象映射_自定义转对象
  • 请求.对象映射_对象转数组
  • 请求.对象映射_数组转对象
  • 请求.对象映射_格式化名称

详细使用方法可以查看[对象映射]文档。

 

附录

常用请求头列表

请求头解释示例
Accept指定客户端能够接收的内容类型Accept: text/plain, text/html
Accept-Charset浏览器可以接受的字符编码集。Accept-Charset: iso-8859-5
Accept-Encoding指定浏览器可以支持的web服务器返回内容压缩编码类型。Accept-Encoding: compress, gzip
Accept-Language浏览器可接受的语言Accept-Language: en,zh
Accept-Ranges可以请求网页实体的一个或者多个子范围字段Accept-Ranges: bytes
AuthorizationHTTP授权的授权证书Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control指定请求和响应遵循的缓存机制Cache-Control: no-cache
Connection表示是否需要持久连接。(HTTP 1.1默认进行持久连接)Connection: close
CookieHTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。Cookie: $Version=1; Skin=new;
Content-Length请求的内容长度Content-Length: 348
Content-Type请求的与实体对应的MIME信息Content-Type: application/x-www-form-urlencoded
Date请求发送的日期和时间Date: Tue, 15-Nov-17 08:12:31 GMT
Expect请求的特定的服务器行为Expect: 100-continue
From发出请求的用户的EmailFrom: user@email.com
Host指定请求的服务器的域名和端口号Host: www.jimstone.com.cn
If-Match只有请求内容与实体相匹配才有效If-Match: “737060cd8c284d8af7ad3082f209582d”
If-Modified-Since如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT
If-None-Match如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变If-None-Match: “737060cd8c284d8af7ad3082f209582d”
If-Range如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为EtagIf-Range: “737060cd8c284d8af7ad3082f209582d”
If-Unmodified-Since只在实体在指定时间之后未被修改才请求成功If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT
Max-Forwards限制信息通过代理和网关传送的时间Max-Forwards: 10
Pragma用来包含实现特定的指令Pragma: no-cache
Proxy-Authorization连接到代理的授权证书Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range只请求实体的一部分,指定范围Range: bytes=500-999
Referer先前网页的地址,当前请求网页紧随其后,即来路Referer: http://www.jimstone.com.cn/english/
TE客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息TE: trailers,deflate;q=0.5
Upgrade向服务器指定某种传输协议以便服务器进行转换(如果支持)Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
User-AgentUser-Agent的内容包含发出请求的用户信息User-Agent: Mozilla/5.0 (Linux; X11)
Via通知中间网关或代理服务器地址,通信协议Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning关于消息实体的警告信息Warn: 199 Miscellaneous warning