Summary
在一个SinatraWeb 应用程序,如何向应用程序发出虚拟请求并以文本形式获取响应正文?例如,这些路线...
get('/foo'){ "foo" }
get('/bar'){ "#{spoof_request '/foo'} - bar" }
...当使用网络浏览器请求“/bar”时,应该得到响应“foo - bar”。
动机
我的应用程序有一个代表错误条目的页面,其中包含有关该错误条目的大量详细信息:错误在哪个版本中遇到、它有多重要、与之关联的标签、错误分配给谁等。
用户可以交互地编辑该页面上的各个数据。使用我的AJAX获取jQuery 插件,JavaScript 使用 AJAX 将页面的只读部分(例如,分配此错误的人员的姓名)替换为 HTML 部分表单,以便仅编辑该部分。用户提交表单,AJAX 对该字段的静态版本发出新请求。
为了DRY,我希望创建页面的 Haml 视图使用与创建各个静态片段时 AJAX 发出的完全相同的请求。例如:
#notifications.section
%h2 Email me if someone...
.section-body= spoof_request "/partial/notifications/#{@bug.id}"
不太有效的代码
以下帮助程序定义spoof_request
在 Sinatra 1.1.2 下工作:
PATH_VARS = %w[ REQUEST_PATH PATH_INFO REQUEST_URI ]
def spoof_request( uri, headers=nil )
new_env = env.dup
PATH_VARS.each{ |k| new_env[k] = uri.to_s }
new_env.merge!(headers) if headers
call( new_env ).last.join
end
然而,在 Sinatra 1.2.3 下,这不再起作用。尽管设置了每一个PATH_VARS
到所需的 URI,call( new_env )
仍然会导致 Sinatra 处理当前请求的路由,而不是指定的路径。 (这会导致无限递归,直到堆栈级别最终触底。)
这个问题不同于从 Sinatra 内部呼叫 Sinatra因为该(旧)问题的接受答案不会维持用户的会话。