Ruby 的 CGI 編程
在本教程中,我們將學(xué)習(xí) Ruby 編程語(yǔ)言中的 CGI(Common Gateway Interface)編程。
1. 什么是 CGI
CGI 是Common Gateway Interface的縮寫,它是用于在萬(wàn)維網(wǎng)和 CGI 程序之間傳送數(shù)據(jù)或信息的標(biāo)識(shí)。CGI 程序提供了一種與用戶進(jìn)行交互的動(dòng)態(tài)方式,并以可以接受和返回?cái)?shù)據(jù)的方式進(jìn)行設(shè)計(jì)。所有處理都在 Web 服務(wù)器上進(jìn)行。因此,它被用作服務(wù)器端解決方案。
簡(jiǎn)單來(lái)說(shuō),就是返回 HTML 代碼。
2. Ruby中編寫CGI的方式
2.1 輸出 Hello World
在 Ruby 中我們要輸出 HTML 代碼的話,應(yīng)該這樣去做。
print "Content-type: text/html\r\n\r\n"
print "<html><body>Hello World!</body></html>\r\n"
# ---- 輸出結(jié)果 ----
Content-type: text/html
<html><body>Hello World!</body></html>
**解釋:**在打印出任何真實(shí)的 HTML 內(nèi)容之前,我們需要發(fā)送 HTML 標(biāo)頭,后跟空白行。至少我們需要打印出Content-type
。下一行將打印內(nèi)容類型,后跟兩個(gè)換行符。第一個(gè)是Content-type
行的結(jié)尾,第二個(gè)是空行的結(jié)尾。例子中最后顯示的是 Hello World。
為了更簡(jiǎn)便地使用 CGI,Ruby 將 CGI 封裝到了 cgi 的庫(kù)里面,您可以在require 'cgi'
之后,創(chuàng)建表單、Cookie、維護(hù)狀態(tài)會(huì)話等。
我們用 cgi 庫(kù)來(lái)實(shí)現(xiàn)剛剛的代碼:
#!/usr/bin/ruby
require 'cgi'
cgi = CGI.new
puts cgi.header
print "<html><body>Hello World!</body></html>\r\n"
# ---- 輸出結(jié)果 ----
Content-Type: text/html
<html><body>Hello World!</body></html>
解釋:
第一行是用來(lái)確認(rèn)系統(tǒng)中使用哪個(gè)解釋器來(lái)理解文件中的代碼。
Tips:如果您在實(shí)行腳本的時(shí)候在終端出現(xiàn):(offline mode: enter name=value pairs on standard input)的提示,請(qǐng)按
ctrl + d
繼續(xù)執(zhí)行腳本。
2.2 輸出表單
HTML 每一個(gè)標(biāo)簽在 CGI 中都有一個(gè)方法。
實(shí)例:
#!/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
}
}
}
}
# ---- 輸出結(jié)果 ----
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>
解釋:
上面的代碼生成了一個(gè)HTMl表單,首頁(yè)我們?yōu)榱耸褂梅椒?,先?shí)例化了CGI,所有的方法都返回一個(gè)字符串,該字符串是標(biāo)簽的內(nèi)容。
2.3 字符串轉(zhuǎn)義
在處理 URL 或 HTML 表單數(shù)據(jù)中的參數(shù)時(shí),需要指定轉(zhuǎn)義特殊字符,例如:引號(hào)(“),斜杠(/)。Ruby CGI 對(duì)象提供CGI.escape
、CGI.unescape
和方法來(lái)轉(zhuǎn)義這些特殊字符:
escape 的例子:
#!/usr/bin/ruby
require 'cgi'
puts CGI.escape(Zara Ali/A Sweet & Sour Girl")
# ---- 輸出結(jié)果 ----
Zara+Ali%2FA+Sweet+%26+Sour+Girl
另一組示例:
#!/usr/bin/ruby
require 'cgi'
puts CGI.escapeHTML('<h1>Zara Ali/A Sweet & Sour Girl</h1>')
# ---- 輸出結(jié)果 ----
<h1>Zara Ali/A Sweet & Sour Girl</h1>
CGI 還有許多的方法,詳細(xì)可以通過(guò)點(diǎn)擊這里查看。
2.4 CGI 的 Cookies
您可以創(chuàng)建一個(gè)名為 cookie 的對(duì)象并存儲(chǔ)文本消息,將信息發(fā)送到瀏覽器,調(diào)用 CGI.out 設(shè)置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
# ---- 輸出結(jié)果 ----
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>
我們回到頁(yè)面時(shí)可以通過(guò)下面的方式獲取到 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 環(huán)境的持久會(huì)話狀態(tài),在需要關(guān)閉會(huì)話后,因此可以確保將數(shù)據(jù)寫入內(nèi)存,當(dāng)會(huì)話結(jié)束時(shí),您需要?jiǎng)h除數(shù)據(jù)。
#!/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}"
}
}
}
# ---- 輸出結(jié)果 ----
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>
會(huì)話數(shù)據(jù)存在于服務(wù)器上的臨時(shí)文件目錄中,prefix 參數(shù)指定會(huì)話的前綴,作為臨時(shí)文件的前綴。在服務(wù)器上,以便您可以輕松識(shí)別不同的會(huì)話臨時(shí)文件。
3. 小結(jié)
本章節(jié)中我們了解了 CGI,學(xué)習(xí)了如何使用 Ruby 的 cgi 庫(kù),來(lái)進(jìn)行頁(yè)面的輸出、表單生成、Cookies 和 Session 的生成與獲取。