跳到内容

XQuery/链式网页表单

来自 Wikibooks,开放的书,为开放的世界

您想创建一个系列的网页,将信息从一个页面传递到下一个页面。这在 web 应用程序开发中非常常见,例如在创建“向导”时,这些向导会在单独的网页上询问用户一系列问题。

我们将使用三种方法来演示这一点

  • 在客户端使用 URL 参数和隐藏表单字段
  • 在客户端使用 Cookies
  • 在服务器上使用会话

使用 URL 参数和隐藏表单字段

[编辑 | 编辑源代码]

在这种方法中,我们将在一系列连续页面中使用 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

[编辑 | 编辑源代码]

在本例中,我们将使用以下函数来设置和获取 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 通常非常适合存储用户首选项。

当您让用户使用登录进行身份验证,但数据在用户注销或会话超时时丢失时,会话最为有用。

华夏公益教科书