如何使用标准库解析Ruby中的URL参数?
我使用以下带有“uri”和“CGI”的代码来解析URL的参数:如何使用标准库解析Ruby中的URL参数?,ruby,http,webserver,Ruby,Http,Webserver,我使用以下带有“uri”和“CGI”的代码来解析URL的参数: require 'socket' require 'uri' require 'CGI' server = TCPServer.new 8888 while session = server.accept request = session.gets p "request", request url = "http://somewebsite.com" + request.sub("GET ", "").sub(
require 'socket'
require 'uri'
require 'CGI'
server = TCPServer.new 8888
while session = server.accept
request = session.gets
p "request", request
url = "http://somewebsite.com" + request.sub("GET ", "").sub(" HTTP/1.1", "").gsub(/(\r|\n)/, "")
uri = URI(url)
params = CGI.parse(uri.query)
p "params", params
session.print "HTTP/1.1 200\r\n" # 1
session.print "Content-Type: text/html\r\n" # 2
session.print "\r\n" # 3
session.print "Hello world! The time is #{Time.now}" #4
session.close
end
我必须通过添加http://somewebsite.com
指向路径,并使用uri
和CGI
函数执行此操作。如果浏览器使用,那么它工作得很好。但是,如果浏览器试图访问或随后立即中断,则表示无法拆分。(在CGI.parse(uri.query)
处失败)
我可以把电话换成
params = uri.query ? CGI.parse(uri.query) : nil
但整个过程似乎有点麻烦,需要创建一个URL,然后如果查询不存在,CGI.parse
就会中断。有没有更好的方法使用标准库来实现这一点?(是否应该使用其他内容而不是uri
和CGI
?)
(使用标准库的优点是可以自动处理%20
的案例和中的多个参数,给出
因此。)你为什么要编造什么?使用
CGI.parse
不需要完整的URI。像这样的方法应该会奏效:
require 'socket'
require 'CGI'
server = TCPServer.new 8888
while session = server.accept
request = session.gets
method, full_path = request.split(' ')
path, params = full_path.split('?')
params = CGI.parse(params.gsub('?','')) if params
session.print "HTTP/1.1 200\r\n" # 1
session.print "Content-Type: text/html\r\n" # 2
session.print "\r\n" # 3
session.print "Hello world! The time is #{Time.now}" #4
session.print "\nparams: #{params}"
p "params:", params
session.close
end
如果您不想了解如何重新发明CGI控制盘,也可以使用Rack。从技术上讲,机架不是标准库的一部分,但它离标准库很近
# Gemfile.rb
gem 'rack'
运行$bundle安装
# application.rb
class Application
# This is the main entry point for Rack
# @param env [Hash]
# @return [Array] status, headers, body
# @see https://www.rubydoc.info/gems/rack/Rack/Request
# @see https://www.rubydoc.info/gems/rack/Rack/Response
def self.call(env)
request = Rack::Request.new(env)
Rack::Response.new(
"Hello " + request.params["name"] || "World",
200,
{ "Content-Type" => "text/plain" }
).finish
end
end
request.params
是一个散列,包含查询字符串参数和POST请求的请求正文参数
# config.ru
require 'rack'
require_relative 'application'
run Application
运行$rackup
以启动服务器。这应该回到webrick。您还可以通过将gems添加到Gemfile来使用thin或puma。是thin
还是puma
优于webrick
?我看到由本地文件启动的webrick未被服务——如何使其服务于本地文件?似乎需要(1)“Hello”+(request.params[“name”]| |“World”)
(2)require./application'
您可以在代码中指定端口,而不是启动rackup-p 8888
?Webrick并不是真正最棒的。我真的很推荐彪马。我认为您可以通过运行应用程序来指定端口,port:8888
,但通常通过设置Procfile来完成。paren在“Hello”+(request.params[“name”]| |“World”)
中实际上什么都不做+
实际上是一种方法,所以“Hello”+请求。params[“name”]| |“World”
评估请求。params[“name”]| |“World”
首先是这样。按空间分割,然后按?
分割,似乎有点低级。。。但我想这是可行的,没有例外情况。。。如果有类似于方法、路径、参数、协议=CGI.split_请求(request)
(它是否属于CGI
)的东西,它会工作得更好吗?顺便说一句,我们也可以使用WeBrick的单行启动,并且能够使用foo.CGI
,并运行Ruby程序。。。在这种情况下,cgi_request=cgi::new(“html4”)
和cgi_请求。params
将随时可用。对于如何解析会话,没有设置规则。get
以字符串形式出现。做最适合您的用例的事情。在我的回答的早期版本中,我有方法、uz、参数、协议、version=request.split(/[\s\/]/)
@nopole您在这里的评论中提出并回答了您自己的问题吗?
# config.ru
require 'rack'
require_relative 'application'
run Application