Sinatra技术问题:erb模板无法显示locals变量求助
问题分析
你遇到的核心问题是Sinatra中每个HTTP请求都是独立的上下文——PUT请求里定义的@resp实例变量,在执行redirect "/submitted/"后会触发一个全新的GET请求,这个新请求完全访问不到之前PUT请求里的变量,所以submitted.erb里的<%= results %>自然拿不到数据。
解决方案
这里提供几种可行的处理方式,你可以根据需求选择:
方案1:直接在PUT请求中渲染模板(不跳转)
如果不需要跳转到新的URL,直接在PUT处理完后渲染submitted.erb即可,这样能直接传递变量:
put '/' do require 'json' # 你的JSON处理逻辑 @resp = JSON.pretty_generate(JSON.parse(json)) erb :submitted, :locals => {:results => @resp} end
然后可以去掉原来的GET /submitted路由,处理完PUT后直接展示结果,变量也能正常传递。
方案2:使用Session存储临时数据
如果必须要跳转到/submitted页面,可以用Sinatra的session来保存处理后的JSON数据,因为session会在请求之间保持状态:
首先要在Sinatra应用开头启用session:
enable :sessions
然后修改PUT和GET路由:
put '/' do require 'json' # 你的JSON处理逻辑 processed_json = JSON.pretty_generate(JSON.parse(json)) session[:processed_json] = processed_json redirect "/submitted/" end get '/submitted/?' do @resp = session[:processed_json] # 可选:用完后清除session里的数据,避免下次访问还能看到旧数据 session.delete(:processed_json) erb :submitted, :locals => {:results => @resp} end
这样在GET请求里就能从session中取出之前处理好的JSON数据了。
方案3:通过URL参数传递(仅适合小数据)
如果你的JSON数据体积很小,可以把它编码后作为URL参数传递,但这种方式不适合大体积数据:
put '/' do require 'json' require 'uri' # 你的JSON处理逻辑 processed_json = JSON.pretty_generate(JSON.parse(json)) encoded_json = URI.encode_www_form_component(processed_json) redirect "/submitted/?data=#{encoded_json}" end get '/submitted/?' do @resp = URI.decode_www_form_component(params[:data]) erb :submitted, :locals => {:results => @resp} end
验证小贴士
不管用哪种方案,都可以在submitted.erb里先加个调试判断,确认变量是否存在:
<pre> <% if results %> <%= results %> <% else %> No data received! <% end %> </pre>
内容的提问来源于stack exchange,提问作者skmen
相关产品推荐
相关产品推荐

