3

我有一个模块化的 Sinatra 应用程序,我想在内容类型要求时将输出编码为 JSON。目前我在我的路线中手动这样做:

get 'someroute' do
    # content-type is actually set with a before filter
    # included only for clarity
    content_type 'application/json', :charset => 'utf-8'
    # .. #
    {:success=>true}.to_json
end

我希望它看起来像这样:

get 'someroute' do
    content_type 'application/json', :charset => 'utf-8'
    # .. #
    {:success=>true}
end

如果检测到适当的内容类型,我想使用 Rack 中间件进行编码。

我一直在尝试使以下工作,但无济于事(内容长度被破坏 - 返回原始内容的内容长度而不是 JSON 编码的内容):

require 'init'

module Rack
  class JSON
    def initialize app
      @app = app
    end
    def call env
      @status, @headers, @body = @app.call env
      if json_response?
        @body = @body.to_json
      end
      [@status, @headers, @body]
    end
    def json_response?
      @headers['Content-Type'] == 'application/json'
    end
  end
end

use Rack::JSON

MyApp.set :run, false
MyApp.set :environment, ENV['RACK_ENV'].to_sym

run MyApp

有什么建议可以让我回到正轨吗?

4

1 回答 1

4

你已经做对了,除了一件事:Rack 期望 body 是一个响应each但不是字符串的对象。把你的身体放在一个数组里。

这可能不是必需的,但如果您想手动设置内容长度,只需将其添加到标题中即可。

if json_response?
  @body = [@body.to_json]
  @headers["Content-Length"] = @body[0].size.to_s
end
于 2010-08-06T19:59:23.547 回答