eva*_*phy 7 jsonp ruby-on-rails dry respond-with ruby-on-rails-3
我正在尝试为我的Rails 3应用程序创建一个JSONP API.现在在我的控制器中,我有很多遵循这种模式的动作:
# This is from my users_controller.rb, as an example
def index
@users = User.all
respond_with(@users, :callback => params[:callback])
end
Run Code Online (Sandbox Code Playgroud)
虽然这是按原样运作的,但我想通过不必重复:callback => params[:callback]每一个动作的呼叫来干它respond_with.我怎样才能做到这一点?
更新:有一件事我已经意识到我的上述代码是丑陋的,该:callback => params[:callback]选项将被传递给任何响应格式,而不仅仅是JSON.以下代码可能更正确:
def index
@users = User.all
respond_with(@users) do |format|
format.json { render :json => @users, :callback => params[:callback]}
end
end
Run Code Online (Sandbox Code Playgroud)
我有几种方法可以解决这个问题,但我无法弄清楚如何使它们工作:
render(可能在应用程序控制器中),以便它接受:jsonp自动包含:callback => params[:callback]参数的选项.这样我可以将上面的代码更改为以下代码,这有点短:def index
@users = User.all
respond_with(@users) do |format|
format.json { render :jsonp => @users}
end
endRun Code Online (Sandbox Code Playgroud)
to_json以解决我的问题.这样我可以省去块,只是打电话respond_with(@users, :responder => 'MyResponder')来解决问题.或许我可以使用plataformatec的响应者gem在应用程序响应器中包含此代码,这样respond_with(@users)就足够了.请注意,从技术上讲,使用回调参数呈现JSON是不正确的,因为您获得了JavaScript响应(对JSON-P回调的函数调用)而不是JSON结果.所以,如果你有
render :json => my_object, :callback => params[:callback]
Run Code Online (Sandbox Code Playgroud)
并且有一个请求/users?callback=func进来,Rails会回答
func({…})
Run Code Online (Sandbox Code Playgroud)
内容类型application/json不正确,因为上面的响应显然不是JSON而是JavaScript.
我使用的解决方案是
def respond_with_json(item)
respond_with do |format|
format.json { render :json => item }
format.js { render :json => item, :callback => params[:callback] }
end
end
Run Code Online (Sandbox Code Playgroud)
无论有没有回调,它都能正确响应.将此应用于上述解决方案,我们得到:
def custom_respond_with(*resources, &block)
options = resources.extract_options!
if params[:callback]
old_block = block
block = lambda do |format|
old_block.call(format) if block_given?
format.js { render :json => resources[0], :callback => params[:callback] }
end
end
respond_with(*(resources << options), &block)
end
Run Code Online (Sandbox Code Playgroud)
还要注意修正resources[0],否则你最终会resources因为splat操作符而包含在一个额外的数组中.
感谢 samuelkadolph 今天在 #rubyonrails IRC 频道中为我提供的帮助。他在这个要点中提供了一个解决方案,为了方便起见,将其复制如下:
def custom_respond_with(*resources, &block)
options = resources.extract_options!
if options[:callback]
old_block = block
block = lambda do |format|
old_block.call(format) if block_given?
format.json { render :json => [] }
end
end
respond_with(*(resources << options), &block)
end
Run Code Online (Sandbox Code Playgroud)
我还没有在我的应用程序中尝试过这个,但我可以看到它应该有效。他还确认,我可以respond_with通过更改此方法的名称并将定义的最后一行更改为 来类似地覆盖该方法本身super(*(resources << options), &block)。
我认为这对我有用。但是,我仍然有兴趣了解如何编写自定义响应程序来完成这项工作。(恕我直言,这将是一个更优雅的解决方案。)
更新:我在我的应用程序中尝试过这个,它可以进行一些小的更改。这是我现在在 ApplicationController 部分中使用的版本private,旨在自动:callback => params[:callback]为 JSON 请求提供选项:
def custom_respond_with(*resources, &block)
options = resources.extract_options!
if params[:callback]
old_block = block
block = lambda do |format|
old_block.call(format) if block_given?
format.json { render :json => resources, :callback => params[:callback] }
end
end
respond_with(*(resources << options), &block)
end
Run Code Online (Sandbox Code Playgroud)
请注意,我必须更改if options[:callback]为if params[:callback]才能使其正常工作。
| 归档时间: |
|
| 查看次数: |
5869 次 |
| 最近记录: |