将HTML表单发布到remote.cgi-用Ruby编写?
我正在一个微软office live服务网站上工作。它有一个联系表,使访问者能够与业主取得联系。我想写一个Ruby脚本,它位于一个单独的服务器上,表单将发布到该服务器上。它将解析表单数据并通过电子邮件将详细信息发送到预设地址。然后,脚本应将浏览器重定向到确认页面 我有一台运行nginx和postfix的ubuntu hardy机器。Ruby已经安装,我们将了解如何使用Thin及其机架功能来处理脚本。现在到了写剧本的时候了,我画了一张空白 这是一个很长的时间,如果我记得正确的过程是这样的将HTML表单发布到remote.cgi-用Ruby编写?,ruby,email,cgi,sinatra,thin,Ruby,Email,Cgi,Sinatra,Thin,我正在一个微软office live服务网站上工作。它有一个联系表,使访问者能够与业主取得联系。我想写一个Ruby脚本,它位于一个单独的服务器上,表单将发布到该服务器上。它将解析表单数据并通过电子邮件将详细信息发送到预设地址。然后,脚本应将浏览器重定向到确认页面 我有一台运行nginx和postfix的ubuntu hardy机器。Ruby已经安装,我们将了解如何使用Thin及其机架功能来处理脚本。现在到了写剧本的时候了,我画了一张空白 这是一个很长的时间,如果我记得正确的过程是这样的 读取H
- 读取HTTP头
- 解析参数
- 发送电子邮件
- 发送重定向头
get'/'{}
就可以开始处理对虚拟主机的请求。为了添加更多内容(以干净的方式),我们只需在主文件中包含一个routes/script.rb
# cgi-bin.rb
# main file loaded as a sinatra app
require 'sinatra'
# load cgi routes
require 'routes/default'
require 'routes/contact'
# 404 behaviour
not_found do
"Sorry, this CGI host does not recognize that request."
end
这些路由文件将调用存储在单独类库中的功能:
# routes/contact.rb
# contact controller
require 'lib/contact/contactTarget'
require 'lib/contact/contactPost'
post '/contact/:target/?' do |target|
# the target for the message is taken from the URL
msg = ContactPost.new(request, target)
redirect msg.action, 302
end
弄明白这样一件简单的事情会让我有一段时间感到恐惧。我希望冷静地让nginx知道.rb文件将被执行,然后继续执行。现在,这个小sinatra应用程序已经启动并运行,如果我想在将来添加额外的功能,我将能够直接投入其中
实施:
ContactPost类处理消息传递方面。它只需要知道请求中的参数和电子邮件的目标。action启动所有操作并返回控制器重定向到的地址
有一个单独的ContactTarget类,它执行一些身份验证,以确保指定的目标接受来自request.referer中给定URL的消息。这是在ContactTarget::accept中处理的?正如我们可以从ContactPost::action方法中猜到的那样
# lib/contact/contactPost.rb
class ContactPost
# ...
def action
return failed unless @target.accept? @request.referer
if send?
successful
else
failed
end
end
# ...
end
ContactPost::successful和ContactPost::failed通过将HTML表单提供的路径与request.referer URI相结合来返回重定向地址。因此,所有行为都在HTML表单中指定。未来使用此脚本的网站只需在用户自己的~/cgi/contact.conf中列出,就可以离开了。这是因为ContactTarget在/home/:target/cgi/contact.conf中查找详细信息。也许有一天这会是不合适的,但就目前而言,这对我来说还不错
send方法非常简单,它创建一个简单电子邮件类的实例并将其发送出去。Email类基本上基于Ruby net/smtp文档中给出的标准用法示例
# lib/email/email.rb
require 'net/smtp'
class Email
def initialize(from_alias, to, reply, subject, body)
@from_alias = from_alias
@from = "cgi_user@host.domain.com"
@to = to
@reply = reply
@subject = subject
@body = body
end
def send
Net::SMTP.start('localhost', 25) do |smtp|
smtp.send_message to_s, @from, @to
end
end
def to_s
<<END_OF_MESSAGE
From: #{@from_alias}
To: #{@to}
Reply-To: #{@from_alias}
Subject: #{@subject}
Date: #{DateTime::now().to_s}
#{@body}
END_OF_MESSAGE
end
end
#lib/email/email.rb
需要“net/smtp”
班级电子邮件
def初始化(从_别名、收件人、回复、主题、正文)
@from_alias=from_alias
@from=“cgi_user@host.domain.com"
@to=to
@答复
@主语
@身体
结束
def发送
Net::SMTP.start('localhost',25)do | SMTP|
smtp.send_message to_s、@from、@to
结束
结束
def至美国
都在网络模块中,下面是一个示例:
@net = Net::HTTP.new 'http://www.foo.com', 80
@params = {:name => 'doris', :email => 'doris@foo.com'}
# Create HTTP request
req = Net::HTTP::Post.new( 'script.cgi', {} )
req.set_form_data @params
# Send request
response = @net.start do |http|
http.read_timeout = 5600
http.request req
end
都在网络模块中,下面是一个示例:
@net = Net::HTTP.new 'http://www.foo.com', 80
@params = {:name => 'doris', :email => 'doris@foo.com'}
# Create HTTP request
req = Net::HTTP::Post.new( 'script.cgi', {} )
req.set_form_data @params
# Send request
response = @net.start do |http|
http.read_timeout = 5600
http.request req
end
Ruby的CGI类可用于编写CGI脚本。请检查:
顺便说一下,不需要读取HTTP头。使用CGI类解析参数将很容易。然后,发送电子邮件并重定向。Ruby的CGI类可用于编写CGI脚本。请检查:
顺便说一下,不需要读取HTTP头。使用CGI类解析参数将很容易。然后,发送电子邮件并重定向。最好的方法可能是使用现有的Ruby库,如Sinatra:
require "rubygems"
require "sinatra"
get "/myurl" do
# params hash available here
# send email
end
您可能希望使用MailFactory来发送实际的电子邮件,但您肯定不需要费心处理标题或解析参数。最好的方法可能是使用现有的Ruby库,如Sinatra:
require "rubygems"
require "sinatra"
get "/myurl" do
# params hash available here
# send email
end
您可能希望使用MailFactory来发送实际的电子邮件,但您肯定不需要费心处理标题或解析参数。谢谢,看起来我需要Net模块来发送电子邮件,但我看不到使用它来读取发布的参数或发送标题的方法。我想也许我把事情复杂化了。我发现,您只需在cgi脚本中打印到标准输出,然后为重定向发送一个文本头。我将寻找一种类似的方法来读取url中给出的参数。一旦完成,我就离开了。谢谢,看起来我需要网络模块来发送电子邮件,但我看不到你的方法