由于ASP.NET开发服务器(VS2012)不允许我们访问LAN上的URL(!!)并且我没有权限配置IIS,因此我尝试使用WEBrick来启动静态网站,获得LAN访问权限。我正在Windows上运行带有vagrant的Ubuntu。
在我的静态网站的根目录中,我创建了一个文件app.rb
,其中包含以下内容:
#app.rb
require 'rubygems'
require 'rack'
class App
def call(env)
return [200, {"Content-Type" => "text/html"}, "index.html"]
end
end
Rack::Handler::WEBrick.run(App.new, :Port => 8080)
当我运行服务器时; ruby app.rb
,并浏览到http://localhost:8080
,它给了我这个错误:
ERROR NoMethodError: undefined method `each' for "index.html":String
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/rack-1.4.5/lib/rack/handler/webrick.rb:71:in `service'
/usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
/usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
/usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'
有没有办法使用WEBrick或Thin来运行静态(HTML / JS)网站?
我遵循了Stuart的建议并将代码更改为:
return [200, {"Content-Type" => "text/html"}, ["index.html"]]
现在,当我浏览到URL时,它会将“index.html”呈现为字符串,而不是呈现文件内容。
答案 0 :(得分:2)
serving a folder over HTTP with WEBrick有一种简单的方法。
至于Rack,它本身并不处理服务文件。您必须通过HTTP读取要提供的文件,并为Rack提供文件的内容,为此您可以尝试这种快速而肮脏的解决方案:
def call(env)
contents = File.open("index.html") { |f| f.read }
return [200, {"Content-Type" => "text/html"}, [contents]]
end
答案 1 :(得分:1)
您的响应正文必须包含在数组中:
return [200, {"Content-Type" => "text/html"}, ["Hello, World!"]]
请注意[
周围的]
和"Hello, World!"
。有关为什么需要Array包装器的说明,请参阅:
特别是Python WSGI specification的这一部分:
对于大型文件,或者对于HTTP流的专门用途(例如多部分“服务器推送”),应用程序可能需要以较小的块提供输出(例如,以避免将大文件加载到存储器中)。有时也会出现这样的情况,即响应的一部分可能很耗时,但是提前发送响应的部分会很有用。
在这些情况下,应用程序通常会返回迭代器(通常是生成器迭代器),它以逐块方式生成输出。这些块可能会被破坏以与多个部分边界(用于“服务器推送”)一致,或者在耗时的任务之前(例如读取磁盘文件的另一个块)。
该规范引用了Python,但Ruby Rack应用程序中的模拟将HTTP响应主体包装在一个数组(或响应each
方法的任何Enumerable)中。
编辑:要解决原始问题的编辑问题,关于如何专门提供index.html
文件,您可以通过读取文件并在Rack响应中输出其内容来实现:< / p>
return [200, {"Content-Type" => "text/html"}, [File.read("index.html")]]
编辑2 :虽然上述内容仅适用于显示index.html
,但如果要提供整个静态资源目录(JS,CSS等),可以尝试使用Rack::Static中间件。{{3}}有关详细信息,请参阅其文档,但我认为您尝试做的事情可以通过以下方式完成:
require 'rack/static'
use Rack::Static, :urls => {"/" => 'index.html'}