在线文档教程
Ruby 2.4

CGI

CGI类

Parent:Object

概观

通用网关接口(CGI)是一种简单的协议,用于将来自Web服务器的HTTP请求传递给独立程序,并将输出返回到Web浏览器。基本上,在环境(GET)或通过$ stdin(POST)传递的请求参数中调用CGI程序,并且打印到$ stdout的所有内容都会返回给客户端。

该文件包含CGI类。这个类提供了检索HTTP请求参数,管理cookie和生成HTML输出的功能。

CGI::Session文件提供会话管理功能; 请参阅该课程以了解更多详情。

有关CGI协议的更多信息,请参阅www.w3.org/CGI/

介绍

CGI是一个大类,提供了几种方法,其中很多方法都是从其他模块中混入的。一些文档在这个类中,一些在模块CGI :: QueryExtension和CGI :: HtmlExtension中。有关处理cookie的具体信息,请参阅CGI :: Cookie,有关会话的信息请参阅CGI :: session.rb(CGI :: Session)。

对于查询,CGI提供了获取环境变量,参数,cookie和多部分请求数据的方法。对于响应,CGI提供了写输出和生成HTML的方法。

请阅读以获得更多详情。示例在底部提供。

查询

CGI类动态地混合参数和cookie解析功能,环境变量访问以及支持从CGI :: QueryExtension模块解析多部分请求(包括上传的文件)。

环境变量

标准CGI环境变量可作为CGI对象的只读属性。以下是这些变量的列表:

AUTH_TYPE HTTP_HOST REMOTE_IDENT CONTENT_LENGTH HTTP_NEGOTIATE REMOTE_USER CONTENT_TYPE HTTP_PRAGMA REQUEST_METHOD GATEWAY_INTERFACE HTTP_REFERER SCRIPT_NAME HTTP_ACCEPT HTTP_USER_AGENT SERVER_NAME HTTP_ACCEPT_CHARSET PATH_INFO SERVER_PORT HTTP_ACCEPT_ENCODING PATH_TRANSLATED SERVER_PROTOCOL HTTP_ACCEPT_LANGUAGE QUERY_STRING SERVER_SOFTWARE HTTP_CACHE_CONTROL REMOTE_ADDR HTTP_FROM REMOTE_HOST

对于这些变量中的每一个,都有一个相同的名称,除了全部小写,并且没有前面的HTTP_。content_length并且server_port是整数; 其余的都是字符串。

参数

方法params()将请求中所有参数的哈希值作为名称/值列表对返回,其中值列表是一个或多个值的数组。CGI对象本身也表现为参数名称到值的哈希值,但仅为每个参数名称返回单个值(作为字符串)。

例如,假设请求包含带有多个值“blue”和“green”的参数“favourite_colours”。以下行为会发生:

cgi.params["favourite_colours"] # => ["blue", "green"] cgi["favourite_colours"] # => "blue"

如果参数不存在,则前一个方法将返回一个空数组,后一个空字符串。测试参数存在的最简单方法是使用has_key?方法。

Cookies

HTTP Cookies将自动从请求中解析出来。它们可以从cookies()访问器获得,该访问器从cookie名称返回一个哈希到CGI :: Cookie对象。

多部分请求

如果请求的方法是POST并且其内容类型是multipart / form-data,那么它可能包含上传的文件。这些由QueryExtension模块存储在请求的参数中。像往常一样,参数名称是文件输入字段的名称属性。但是,该值不是一个字符串,而是一个IO对象,可以是小文件的IOString,也可以是大文件的Tempfile。这个对象还有其他的单例方法:

local_path()

上传文件在本地文件系统上的路径

original_filename()

客户端计算机上文件的名称

content_type()

文件的内容类型

回应

CGI类提供了将头文件和内容输出发送到HTTP客户端的方法,并混合了用于从CGI :: HtmlExtension和CGI :: TagMaker模块进行编程HTML生成的方法。用于HTML生成的精确版本的HTML在对象创建时指定。

写输出

将输出发送到HTTP客户端的最简单方法是使用out()方法。这将HTTP标头作为散列参数,并通过块将主体内容。可以使用http_header()方法将标题生成为字符串。输出流可以使用print()方法直接写入。

生成HTML

每个HTML元素都有一个用于将该元素生成为String的相应方法。此方法的名称与元素的名称相同,均为小写。元素的属性作为散列传入,而主体作为无参数块计算为String。HTML生成模块知道哪些元素始终为空,并以静默方式丢弃任何传入的主体。它也知道哪些元素需要匹配结束标签,哪些不需要。但是,它不知道哪些属性对于哪些元素是合法的。

CGI :: HtmlExtension模块中还有一些额外的HTML生成方法。这些包括用于不同类型的表单输入的单独方法,以及通常在属性可以直接指定为参数而不是通过散列指定特定属性的元素的方法。

实用程序HTML转义和其他方法(如函数)。

在cgi / util.rb中定义了一些实用工具。当包含时,您可以使用实用程序方法(如函数)。

使用示例

获取表单值

require "cgi" cgi = CGI.new value = cgi['field_name'] # <== value string for 'field_name' # if not 'field_name' included, then return "". fields = cgi.keys # <== array of field names # returns true if form has 'field_name' cgi.has_key?('field_name') cgi.has_key?('field_name') cgi.include?('field_name')

警告!cgi使用旧的cgi.rb返回一个数组(包含在Ruby 1.6中)

获取表单值作为散列

require "cgi" cgi = CGI.new params = cgi.params

cgi.params是一个散列。

cgi.params['new_field_name'] = ["value"] # add new param cgi.params['field_name'] = ["new_value"] # change value cgi.params.delete('field_name') # delete param cgi.params.clear # delete all params

将表单值保存到文件

require "pstore" db = PStore.new("query.db") db.transaction do db["params"] = cgi.params end

从文件恢复表单值

require "pstore" db = PStore.new("query.db") db.transaction do cgi.params = db["params"] end

获取多部分表单值

require "cgi" cgi = CGI.new value = cgi['field_name'] # <== value string for 'field_name' value.read # <== body of value value.local_path # <== path to local file of value value.original_filename # <== original filename of value value.content_type # <== content_type of value

并且值具有StringIO或Tempfile类方法。

获取cookie值

require "cgi" cgi = CGI.new values = cgi.cookies['name'] # <== array of 'name' # if not 'name' included, then return []. names = cgi.cookies.keys # <== array of cookie names

和cgi.cookies是一个散列。

获取cookie对象

require "cgi" cgi = CGI.new for name, cookie in cgi.cookies cookie.expires = Time.now + 30 end cgi.out("cookie" => cgi.cookies) {"string"} cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... } require "cgi" cgi = CGI.new cgi.cookies['name'].expires = Time.now + 30 cgi.out("cookie" => cgi.cookies['name']) {"string"}

打印http头和html字符串到$ DEFAULT_OUTPUT($>)

require "cgi" cgi = CGI.new("html4") # add HTML generation methods cgi.out do cgi.html do cgi.head do cgi.title { "TITLE" } end + cgi.body do cgi.form("ACTION" => "uri") do cgi.p do cgi.textarea("get_text") + cgi.br + cgi.submit end end + cgi.pre do CGI::escapeHTML( "params: #{cgi.params.inspect}\n" + "cookies: #{cgi.cookies.inspect}\n" + ENV.collect do |key, value| "#{key} --> #{value}\n" end.join("") ) end end end end # add HTML generation methods CGI.new("html3") # html3.2 CGI.new("html4") # html4.01 (Strict) CGI.new("html4Tr") # html4.01 Transitional CGI.new("html4Fr") # html4.01 Frameset CGI.new("html5") # html5

一些实用方法

require 'cgi/util' CGI.escapeHTML('Usage: foo "bar" <baz>')

一些实用方法,如函数

require 'cgi/util' include CGI::Util escapeHTML('Usage: foo "bar" <baz>') h('Usage: foo "bar" <baz>') # alias

常量

CR

用于回车的字符串

EOL

标准的互联网新行顺序

HTTP_STATUS

HTTP status codes.

LF

换行的字符串

MAX_MULTIPART_COUNT

multipart时请求参数的最大数目

NEEDS_BINMODE

在二进制文本中是否需要处理

PATH_SEPARATOR

路径分隔符在不同的环境中。

属性

accept_charsetR

返回此CGI实例的接受字符集。

公共类方法

accept_charset()显示源文件

返回所有新CGI实例的接受字符集。

# File lib/cgi/core.rb, line 739 def self.accept_charset @@accept_charset end

accept_charset =(accept_charset)显示源文件

为所有新的CGI实例设置接受字符集。

# File lib/cgi/core.rb, line 744 def self.accept_charset=(accept_charset) @@accept_charset=accept_charset end

new(tag_maker) { block } 显示源文件

new(options_hash = {}) { block }

创建一个新的CGI实例。

tag_maker

这与使用options_hash具有值的表单相同。{ :tag_maker => tag_maker }请注意,建议使用options_hash表单,因为它还允许指定您将接受的字符集。

options_hash

识别三个选项的哈希表:

:accept_charset

指定收到的查询字符串的编码。如果省略,@@accept_charset则被使用。如果编码无效,则会引发CGI :: InvalidEncoding。

例。假设@@accept_charset是“UTF-8”

未指定时:

cgi=CGI.new # @accept_charset # => "UTF-8"

当指定为“EUC-JP”时:

cgi=CGI.new(:accept_charset => "EUC-JP") # => "EUC-JP"

:tag_maker

指定要使用哪种版本的HTML生成方法的字符串。如果未指定,则不会加载HTML生成方法。

支持以下值:

“html3”

HTML 3.x

“html4”

HTML 4.0

“html4Tr”

HTML 4.0过渡

“html4Fr”

带框架的HTML 4.0

“html5”

HTML 5

`:max_multipart_length`

指定多部分数据的最大长度。可以是整数标量或lambda,将在解析请求时进行评估。这允许在确定是否接受多部分数据时设置更复杂的逻辑(例如咨询注册用户上传津贴)

默认值是128 * 1024 * 1024字节

cgi=CGI.new(:max_multipart_length => 268435456) # simple scalar cgi=CGI.new(:max_multipart_length => -> {check_filesystem}) # lambda

`block`

如果提供,则在遇到无效编码时调用该块。例如:

encoding_errors={} cgi=CGI.new(:accept_charset=>"EUC-JP") do |name,value| encoding_errors[name] = value end

最后,如果CGI对象不是在标准CGI调用环境中创建的(也就是说,它不能在其环境中定位REQUEST_METHOD),那么它将以“脱机”模式运行。在此模式下,它从命令行读取参数或从标准输入读取(失败)参数。否则,cookies和其他参数将从标准CGI位置自动分析,这取决于REQUEST_METHOD。

# File lib/cgi/core.rb, line 830 def initialize(options = {}, &block) # :yields: name, value @accept_charset_error_block = block_given? ? block : nil @options={ :accept_charset=>@@accept_charset, :max_multipart_length=>@@max_multipart_length } case options when Hash @options.merge!(options) when String @options[:tag_maker]=options end @accept_charset=@options[:accept_charset] @max_multipart_length=@options[:max_multipart_length] if defined?(MOD_RUBY) && !ENV.key?("GATEWAY_INTERFACE") Apache.request.setup_cgi_env end extend QueryExtension @multipart = false initialize_query() # set @params, @cookies @output_cookies = nil @output_hidden = nil case @options[:tag_maker] when "html3" require 'cgi/html' extend Html3 extend HtmlExtension when "html4" require 'cgi/html' extend Html4 extend HtmlExtension when "html4Tr" require 'cgi/html' extend Html4Tr extend HtmlExtension when "html4Fr" require 'cgi/html' extend Html4Tr extend Html4Fr extend HtmlExtension when "html5" require 'cgi/html' extend Html5 extend HtmlExtension end end

parse(query) Show source

将HTTP查询字符串解析为key =>值对的散列。

params = CGI::parse("query_string") # {"name1" => ["value1", "value2", ...], # "name2" => ["value1", "value2", ...], ... }

# File lib/cgi/core.rb, line 374 def CGI::parse(query) params = {} query.split(/[&;]/).each do |pairs| key, value = pairs.split('=',2).collect{|v| CGI::unescape(v) } next unless key params[key] ||= [] params[key].push(value) if value end params.default=[].freeze params end

公共实例方法

header(options='text/html')

当HTML5标记制作器处于非活动状态时,此方法是http_header的别名。

注:使用http_header创建HTTP头块,此别名仅用于向后兼容。

使用标头与HTML5标签制造商将创建一个<header>元素。

别名为:http_header

http_header(content_type_string="text/html") Show source

http_header(headers_hash)

创建一个HTTP标头块作为一个字符串。

包含结束标题块的空行。

content_type_string

如果使用这种形式,这个字符串就是 Content-Type

headers_hash

标头值的哈希值。以下标题键被识别:

type

Content-Type标头。默认为“text / html”

charset

附加到Content-Type标题的正文的字符集。

nph

一个布尔值。如果为true,则预先输入协议字符串和状态代码以及日期; 如果未明确设置,则为“服务器”和“连接”设置默认值。

status

HTTP状态码作为字符串返回,作为状态头。这些值是:

OK

200 OK

PARTIAL_CONTENT

206部分内容

MULTIPLE_CHOICES

300多种选择

MOVED

301永久移动

REDIRECT

302 Found

NOT_MODIFIED

304未修改

BAD_REQUEST

400错误请求

AUTH_REQUIRED

401需要授权

FORBIDDEN

403 Forbidden

NOT_FOUND

404 Not Found

METHOD_NOT_ALLOWED

405 Method Not Allowed

NOT_ACCEPTABLE

406 Not Acceptable

LENGTH_REQUIRED

411 Length Required

PRECONDITION_FAILED

412 Precondition Failed

SERVER_ERROR

500 Internal Server Error

NOT_IMPLEMENTED

501 Method Not Implemented

BAD_GATEWAY

502 Bad Gateway

VARIANT_ALSO_VARIES

506 Variant Also Negotiates

server

服务器软件作为Server头返回。

connection

连接类型,作为Connection标题返回(例如,“close”)。

length

将发送的内容的长度作为Content-Length标题返回。

language

内容的语言,作为Content-Language头文件返回。

expires

当前内容作为Time对象过期的时间作为Expires标题返回。

cookie

作为一个或多个Set-Cookie标题返回的Cookie或Cookie。该值可以是cookie的文字字符串; 一个CGI :: Cookie对象; 一组字面cookie字符串或Cookie对象; 或者它们的值都是文字cookie字符串或Cookie对象的散列。

这些cookie除了保存在@output_cookies字段中的Cookie之外。

其他标题也可以设置; 它们被附加为key:value。

例子:

http_header # Content-Type: text/html http_header("text/plain") # Content-Type: text/plain http_header("nph" => true, "status" => "OK", # == "200 OK" # "status" => "200 GOOD", "server" => ENV['SERVER_SOFTWARE'], "connection" => "close", "type" => "text/html", "charset" => "iso-2022-jp", # Content-Type: text/html; charset=iso-2022-jp "length" => 103, "language" => "ja", "expires" => Time.now + 30, "cookie" => [cookie1, cookie2], "my_header1" => "my_value" "my_header2" => "my_value")

此方法不执行字符集转换。

# File lib/cgi/core.rb, line 152 def http_header(options='text/html') if options.is_a?(String) content_type = options buf = _header_for_string(content_type) elsif options.is_a?(Hash) if options.size == 1 && options.has_key?('type') content_type = options['type'] buf = _header_for_string(content_type) else buf = _header_for_hash(options.dup) end else raise ArgumentError.new("expected String or Hash but got #{options.class}") end if defined?(MOD_RUBY) _header_for_modruby(buf) return '' else buf << EOL # empty line of separator return buf end end

另外别名为:标题

out(content_type_string='text/html') Show source

out(headers_hash)

将HTTP头和正文打印到$ DEFAULT_OUTPUT($>)

content_type_string

如果传递一个字符串,则假定它是内容类型。

headers_hash

这是一个哈希标头,与http_header使用的相似。

block

一个块是必需的,应该评估响应的主体。

Content-Length 是根据内容块返回的字符串的大小自动计算的。

如果ENV['REQUEST_METHOD'] == "HEAD",则仅输出标题(内容块仍然是必需的,但它被忽略)。

如果字符集是“iso-2022-jp”或“euc-jp”或“shift_jis”,则内容转换为该字符集,并将语言设置为“ja”。

例:

cgi = CGI.new cgi.out{ "string" } # Content-Type: text/html # Content-Length: 6 # # string cgi.out("text/plain") { "string" } # Content-Type: text/plain # Content-Length: 6 # # string cgi.out("nph" => true, "status" => "OK", # == "200 OK" "server" => ENV['SERVER_SOFTWARE'], "connection" => "close", "type" => "text/html", "charset" => "iso-2022-jp", # Content-Type: text/html; charset=iso-2022-jp "language" => "ja", "expires" => Time.now + (3600 * 24 * 30), "cookie" => [cookie1, cookie2], "my_header1" => "my_value", "my_header2" => "my_value") { "string" } # HTTP/1.1 200 OK # Date: Sun, 15 May 2011 17:35:54 GMT # Server: Apache 2.2.0 # Connection: close # Content-Type: text/html; charset=iso-2022-jp # Content-Length: 6 # Content-Language: ja # Expires: Tue, 14 Jun 2011 17:35:54 GMT # Set-Cookie: foo # Set-Cookie: bar # my_header1: my_value # my_header2: my_value # # string

# File lib/cgi/core.rb, line 348 def out(options = "text/html") # :yield: options = { "type" => options } if options.kind_of?(String) content = yield options["length"] = content.bytesize.to_s output = stdoutput output.binmode if defined? output.binmode output.print http_header(options) output.print content unless "HEAD" == env_table['REQUEST_METHOD'] end

print(*options) Show source

将参数或参数列表打印到默认输出流

cgi = CGI.new cgi.print # default: cgi.print == $DEFAULT_OUTPUT.print

# File lib/cgi/core.rb, line 364 def print(*options) stdoutput.print(*options) end

私有实例方法

env_table() Show source

ENV的同义词。

# File lib/cgi/core.rb, line 51 def env_table ENV end

stdinput() Show source

$ stdin的同义词。

# File lib/cgi/core.rb, line 56 def stdinput $stdin end

stdoutput() Show source

$ stdout的同义词。

# File lib/cgi/core.rb, line 61 def stdoutput $stdout end