2

由于 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)网站?

编辑

我按照斯图尔特的建议将代码更改为:

return [200, {"Content-Type" => "text/html"}, ["index.html"]]

现在,当我浏览 URL 时,它会将“index.html”呈现为字符串,而不是呈现文件内容。

4

2 回答 2

2

有一种使用 WEBrick 通过 HTTP 提供文件夹的简单方法。

至于 Rack,它本身并不处理提供文件。你必须阅读你想通过 HTTP 服务的文件,并给 Rack 文件的内容,为此你可以尝试这个快速而肮脏的解决方案:

def call(env)
  contents = File.open("index.html") { |f| f.read }
  return [200, {"Content-Type" => "text/html"}, [contents]]
end
于 2013-05-07T10:25:22.350 回答
1

您的响应正文必须包装在一个数组中:

    return [200, {"Content-Type" => "text/html"}, ["Hello, World!"]]

注意[]周围"Hello, World!"。有关为什么需要 Array 包装器的说明,请参阅:

为什么机架响应体是数组而不是字符串?

特别是Python WSGI 规范的这一部分:

然而,对于大文件或 HTTP 流的特殊用途(例如多部分“服务器推送”),应用程序可能需要以较小的块提供输出(例如,避免将大文件加载到内存中)。有时,生成响应的一部分可能会很耗时,但提前发送响应之前的响应部分会很有用。

在这些情况下,应用程序通常会返回一个迭代器(通常是生成器-迭代器),它以逐块方式生成输出。这些块可能会被破坏以与多部分边界重合(用于“服务器推送”),或者就在耗时的任务之前(例如读取磁盘文件的另一个块)。

该规范指的是 Python,但 Ruby Rack 应用程序中的类似物是将 HTTP 响应主体包装在一个数组(或任何响应该each方法的 Enumerable)中。

编辑:要解决原始问题的编辑,关于如何专门提供index.html文件,您可以通过读取文件并在 Rack 响应中输出其内容来做到这一点:

    return [200, {"Content-Type" => "text/html"}, [File.read("index.html")]]

编辑 2:虽然上述内容index.html仅用于显示,但如果您想提供静态资源(JS、CSS 等)的整个目录,您可以尝试使用Rack::Static中间件。有关详细信息,请参阅其文档,但我认为您尝试做的事情可以通过以下方式完成:

require 'rack/static'
use Rack::Static, :urls => {"/" => 'index.html'}
于 2013-05-07T09:01:21.793 回答