服务端相关 / 50 Ruby 的 CGI 编程

Ruby 的 CGI 编程

在本教程中,我们将学习 Ruby 编程语言中的 CGI(Common Gateway Interface)编程。

1. 什么是 CGI

CGI 是Common Gateway Interface的缩写,它是用于在万维网和 CGI 程序之间传送数据或信息的标识。CGI 程序提供了一种与用户进行交互的动态方式,并以可以接受和返回数据的方式进行设计。所有处理都在 Web 服务器上进行。因此,它被用作服务器端解决方案。

简单来说,就是返回 HTML 代码。

2. Ruby中编写CGI的方式

2.1 输出 Hello World

在 Ruby 中我们要输出 HTML 代码的话,应该这样去做。

print "Content-type: text/html\r\n\r\n"
print "<html><body>Hello World!</body></html>\r\n"

# ---- 输出结果 ----
Content-type: text/html

<html><body>Hello World!</body></html>

**解释:**在打印出任何真实的 HTML 内容之前,我们需要发送 HTML 标头,后跟空白行。至少我们需要打印出Content-type。下一行将打印内容类型,后跟两个换行符。第一个是Content-type行的结尾,第二个是空行的结尾。例子中最后显示的是 Hello World。

为了更简便地使用 CGI,Ruby 将 CGI 封装到了 cgi 的库里面,您可以在require 'cgi'之后,创建表单、Cookie、维护状态会话等。

我们用 cgi 库来实现刚刚的代码:

#!/usr/bin/ruby

require 'cgi'

cgi = CGI.new
puts cgi.header
print "<html><body>Hello World!</body></html>\r\n"

# ---- 输出结果 ----
Content-Type: text/html

<html><body>Hello World!</body></html>

解释:

第一行是用来确认系统中使用哪个解释器来理解文件中的代码。

Tips:如果您在实行脚本的时候在终端出现:(offline mode: enter name=value pairs on standard input)的提示,请按ctrl + d继续执行脚本。

2.2 输出表单

HTML 每一个标签在 CGI 中都有一个方法。

实例:

#!/usr/bin/ruby

require "cgi"
cgi = CGI.new("html5")
cgi.out {
   cgi.html {
      cgi.head { "\n"+cgi.title{"It is an Example of form"} } +
      cgi.body { "\n"+
         cgi.form {"\n"+
            cgi.hr +
            cgi.h1 { "A Form: " } + "\n"+
            cgi.h2 { "A Basic Form:"} + "\n" +
            cgi.textarea("get_text") +"\n"+
            cgi.button("click_here") +"\n"+
            cgi.hr +
            cgi.br +
            cgi.submit
         }
      }
   }
}

# ---- 输出结果 ----
Content-Type: text/html
Content-Length: 317

<!DOCTYPE HTML><HTML><HEAD>
<TITLE>It is an Example of form</TITLE></HEAD><BODY>
<FORM METHOD="post" ENCTYPE="application/x-www-form-urlencoded">
<HR><H1>A Form: </H1>
<H2>A Basic Form:</H2>
<TEXTAREA NAME="get_text" COLS="70" ROWS="10"></TEXTAREA>
<BUTTON></BUTTON>
<HR><BR><INPUT TYPE="submit"></FORM></BODY></HTML>

解释:

上面的代码生成了一个HTMl表单,首页我们为了使用方法,先实例化了CGI,所有的方法都返回一个字符串,该字符串是标签的内容。

2.3 字符串转义

在处理 URL 或 HTML 表单数据中的参数时,需要指定转义特殊字符,例如:引号(“),斜杠(/)。Ruby CGI 对象提供CGI.escapeCGI.unescape和方法来转义这些特殊字符:

escape 的例子:

#!/usr/bin/ruby

require 'cgi'
puts CGI.escape(Zara Ali/A Sweet & Sour Girl")

# ---- 输出结果 ----
Zara+Ali%2FA+Sweet+%26+Sour+Girl

另一组示例:

#!/usr/bin/ruby

require 'cgi'
puts CGI.escapeHTML('<h1>Zara Ali/A Sweet & Sour Girl</h1>')

# ---- 输出结果 ----
&lt;h1&gt;Zara Ali/A Sweet &amp; Sour Girl&lt;/h1&gt;

CGI 还有许多的方法,详细可以通过点击这里查看。

2.4 CGI 的 Cookies

您可以创建一个名为 cookie 的对象并存储文本消息,将信息发送到浏览器,调用 CGI.out 设置cookie头:

#!/usr/bin/ruby

require "cgi"
cgi = CGI.new("html5")
cookie = CGI::Cookie.new('name' => 'mycookie',
                         'value' => 'Zara Ali',
                         'expires' => Time.now + 3600)
cgi.out('cookie' => cookie) do
   cgi.head + cgi.body { "Cookie stored" }
end

# ---- 输出结果 ----
Content-Type: text/html
Content-Length: 32
Set-Cookie: mycookie=Zara+Ali; path=; expires=Sun, 30 Aug 2020 18:01:17 GMT

<HEAD><BODY>Cookie stored</BODY>

我们回到页面时可以通过下面的方式获取到 Cookies:

#!/usr/bin/ruby

require "cgi"
cgi = CGI.new("html5")
cookie = cgi.cookies['mycookie']
cgi.out('cookie' => cookie) do
   cgi.head + cgi.body { cookie[0] }
end

2.5 CGI 的 Sessions

CGI::Session可以保存为用户和 CGI 环境的持久会话状态,在需要关闭会话后,因此可以确保将数据写入内存,当会话结束时,您需要删除数据。

#!/usr/bin/ruby
require 'cgi'
require 'cgi/session'
cgi = CGI.new("html4")

sess = CGI::Session.new( cgi, "session_key" => "a_test", "prefix" => "rubysess.")
lastaccess = sess["lastaccess"].to_s
sess["lastaccess"] = Time.now
if cgi['bgcolor'][0] =~ /[a-z]/
  sess["bgcolor"] = cgi['bgcolor']
end

cgi.out{
  cgi.html {
    cgi.body("bgcolor" => sess["bgcolor"]) {
      "The background of this page"    +
      "changes based on the 'bgcolor'" +
      "each user has in session."      +
      "Last access time: #{lastaccess}"
    }
  }
}

# ---- 输出结果 ----
Content-Type: text/html
Content-Length: 216
Set-Cookie: a_test=8239f376c9e2cb2b77a0512bb3b8fa0b; path=

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><HTML><BODY>The background of this pagechanges based on the 'bgcolor'each user has in session.Last access time: </BODY></HTML>

会话数据存在于服务器上的临时文件目录中,prefix 参数指定会话的前缀,作为临时文件的前缀。在服务器上,以便您可以轻松识别不同的会话临时文件。

3. 小结

本章节中我们了解了 CGI,学习了如何使用 Ruby 的 cgi 库,来进行页面的输出、表单生成、Cookies 和 Session 的生成与获取。