XQuery/链式网页表单
您想创建一个系列的网页,将信息从一个页面传递到下一个页面。这在 web 应用程序开发中非常常见,例如在创建“向导”时,这些向导会在单独的网页上询问用户一系列问题。
我们将使用三种方法来演示这一点
- 在客户端使用 URL 参数和隐藏表单字段
- 在客户端使用 Cookies
- 在服务器上使用会话
在这种方法中,我们将在一系列连续页面中使用 HTML 表单。每个页面都会收集一些信息,并通过向 URL 添加额外的参数,将这些信息传递给下一个表单。我们将使用 request:get-parameter 函数从 URL 获取键值对。
我们的第一个表单将询问用户他们的姓名。第二个将询问他们最喜欢的颜色。
以下是一个第一个表单的示例
question-1.html
<html>
<head>
<title>Question 1: Your Name</title>
</head>
<body>
<h1>Question 1</h1>
<form action="question-2.xq">
<span class="label">Please enter your first name:</span>
<input type="text" name="name"/><br/>
<input type="submit" value="Next Question"/>
</form>
</body>
</html>
URL 被传递给第二个表单,我们将使用 request:get-parameter() 函数从 URL 获取值。
以下是 question 2 的 XQuery 函数:question-2.xq
xquery version "1.0";
declare option exist:serialize "method=xhtml media-type=text/html omit-xml-declaration=yes indent=yes";
let $name := request:get-parameter('name', '')
let $title := 'Question 2: Enter Your Favorite Color'
return
<html>
<head>
<title>{$title}</title>
</head>
<body>
<h1>{$title}</h1>
<form action="result.xq">
<span class="label">Hello {$name}. Please enter your favorite color:</span>
<input type="hidden" name="name" value="{$name}"/>
<input type="text" name="color"/><br/>
<input type="submit" value="Results"/>
</form>
</body>
</html>
请注意,我们将传入的姓名存储在表单中的一个隐藏输入字段中。隐藏字段的值必须取自传入的 {$name} 参数。
最后一页只获取两个输入参数,并在 HTML 页面中显示它们。如果您查看 URL,它将采用以下格式
result.xq?name=dan&color=blue
result.xq
xquery version "1.0";
declare option exist:serialize "method=xhtml media-type=text/html omit-xml-declaration=yes indent=yes";
let $name := request:get-parameter('name', '')
let $color := request:get-parameter('color', '')
let $title := 'Result'
return
<html>
<head>
<title>{$title}</title>
</head>
<body>
<h1>{$title}</h1>
<p>Hello {$name}. Your favorite color is {$color}</p>
</body>
</html>
这种方法是首选方法,因为它不需要客户端浏览器支持 Cookies。它也不需要用户登录和管理会话。会话的缺点是,如果用户在中途被打断,他们的会话信息将丢失,他们输入的所有数据都需要重新输入。
请注意,虽然第一个“姓名”参数在第二个表单中不可见,但该值在 URL 中可见。因此,“隐藏”一词不适用于 URL,只适用于表单。
在本例中,我们将使用以下函数来设置和获取 Cookies
response:set-cookie($name as xs:string, $value as xs:string) empty() request:get-cookie-value($cookie-name as xs:string) xs:string?
第一个表单与上面的示例相同。但是,
xquery version "1.0";
declare option exist:serialize "method=xhtml media-type=text/html omit-xml-declaration=yes indent=yes";
(: get the input and set the name cookie :)
let $name := request:get-parameter('name', '')
let $set-cookie := response:set-cookie('name', $name)
let $title := 'Question 2: Enter Your Favorite Color'
return
<html>
<head>
<title>{$title}</title>
</head>
<body>
<h1>{$title}</h1>
<form action="result.xq">
<span class="label">Hello {$name}. Please enter your favorite color:</span>
<input type="text" name="color"/><br/>
<input type="submit" value="Results"/>
</form>
</body>
</html>
我们的第一个表单将设置第一个 Cookie 值,而第二个表单将读取姓名 Cookie 的值。
xquery version "1.0";
declare option exist:serialize "method=xhtml media-type=text/html omit-xml-declaration=yes indent=yes";
let $name := request:get-cookie-value('name')
let $color := request:get-parameter('color', '')
let $title := 'Result From Cookies'
return
<html>
<head>
<title>{$title}</title>
</head>
<body>
<h1>{$title}</h1>
<p>Hello {$name}. Your favorite color is {$color}</p>
</body>
</html>
使用 Cookies 可能很复杂,您必须非常小心,不要让来自同一域的其他应用程序更改您的 Cookies。您的设计还必须考虑浏览器和用户禁用 Cookies 的事实。
最后一种方法是使用服务器会话值来存储键值数据。这将与最后一个示例非常相似,但我们将使用 eXist 会话 模块函数来设置和获取值。
以下是我们需要调用的两个函数
session:set-attribute($name as xs:string, $value as item()*) empty() session:get-attribute($name as xs:string) xs:string*
您只需要更改第二种表单的一行。只需将以下几行更改为:
(: get the name and set the session :) let $name := request:get-parameter('name', ) let $set-session := session:set-attribute('name', $name)
在最后的 result 脚本中,只需从会话中获取数据即可
let $name := session:get-attribute('name')
如果您不熟悉会话管理,使用会话也可能很复杂。有很多规则管理会话超时,web 服务器和数据库服务器可能都需要配置,以满足用户的需求。会话管理可能也不适合那些禁止在 web 服务器上收集信息的公共网站。
有很多方面需要考虑。在 URL 中存储信息有很多优势,因为用户可以启动一个多步骤表单,然后稍后回来完成。只要他们没有关闭浏览器,URL 参数就会保留。
Cookies 会保留在客户端,直到用户采取一些操作将其删除。当您不想让用户在每次会话中重新输入数据时,它们非常有用。当您没有能力在服务器上存储用户首选项时,Cookies 通常非常适合存储用户首选项。
当您让用户使用登录进行身份验证,但数据在用户注销或会话超时时丢失时,会话最为有用。