Rails 页面缓存和自动扩展的问题
我有一个基于 JSON
和 XML
的 API,需要进行页面缓存。我已经在 api 上设置了路由,以将格式作为 URL 的一部分包含在内,这样 URL 就可以这样工作:
http://example.com/foo/1/bar/2/xml
http://example.com/foo/1/bar/2/json
我看到的问题是,在服务器的 public
文件夹中,文件正在保存例如 xml.xml
和 json.json
,这会导致下次访问 URL 时缓存未命中。
有没有办法:
- 关闭自动扩展生成,以便保存它们时根本没有扩展? (例如:
RAILS_ROOT/public/foo/1/bar/2/json
) - 每次调用时强制所有扩展名均为
.html
。 (例如:RAILS_ROOT/public/foo/1/bar/2/json.html)
其中任何一个都会导致我的服务器返回缓存的文件而不是丢失。我该怎么做?
编辑:
有人询问相关路线:
scope '(foo/:foo_id)', :foo_id => /\d+/ do
get '/bar/:bar_id/:format' => 'bars#show', :bar_id => /\d+/, :format => /json|xml|html/
end
解决方案:
当我正在寻找一种使用内置页面缓存支持来实现这一点的官方方法时,我最终只使用了后过滤器和我自己的页面缓存方法,如 Anton 所建议的
# application_controller.rb
def cache_api_page
if REDACTEDServer::Application.config.action_controller.perform_caching
self.class.cache_page(response.body, request.path, '')
puts "CACHED PATH: #{request.path}"
end
end
# bar_controller.rb
after_filter :cache_api_page, :only => [ :show, :index ]
I have a JSON
and XML
based API that needs to be page cached. I have setup my routes on the api to include the format as part of the URL, such that URL's like this work:
http://example.com/foo/1/bar/2/xml
http://example.com/foo/1/bar/2/json
The problem I am seeing is that in the server's public
folder, the files are being saved as xml.xml
and json.json
, and this causes cache misses the next time the URL is accessed.
Is there a way to either:
- Turn off the auto extension generation so that they are saved without an extension at all? (EX:
RAILS_ROOT/public/foo/1/bar/2/json
) - Force all the extensions to be
.html
for every call. (EX:RAILS_ROOT/public/foo/1/bar/2/json.html
)
Either of these would cause my server to return the cached file instead of a miss. How can I do this?
EDIT:
Somebody asked for the relevant route:
scope '(foo/:foo_id)', :foo_id => /\d+/ do
get '/bar/:bar_id/:format' => 'bars#show', :bar_id => /\d+/, :format => /json|xml|html/
end
SOLUTION:
While I was looking for an official way to make this happen using the built in page caching support, I ended up just using an after filter and my own page cache method, as suggested by Anton
# application_controller.rb
def cache_api_page
if REDACTEDServer::Application.config.action_controller.perform_caching
self.class.cache_page(response.body, request.path, '')
puts "CACHED PATH: #{request.path}"
end
end
# bar_controller.rb
after_filter :cache_api_page, :only => [ :show, :index ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你可以这样做:
当 http://example.com/foo/1/bar /2/json 被访问,它将写入页面到缓存 (RAILS_ROOT/public/foo/1/bar/2/json.html)
如果你得到 http://example.com/foo/1/bar/2/json 再次,您收到 RAILS_ROOT/public/foo/1/bar/2/json.html,但是您的 http服务器(Apache?)应该知道该文件的内容类型。
否则内容类型将设置为“text/html”
更新
给您.htaccess
You can do that like this:
When http://example.com/foo/1/bar/2/json is accessed, it will write page to cache (RAILS_ROOT/public/foo/1/bar/2/json.html)
And if you get http://example.com/foo/1/bar/2/json again, you receive RAILS_ROOT/public/foo/1/bar/2/json.html, but your http server(Apache?) should know about content type of this files.
Otherwise content type will set to 'text/html'
UPDATE
To you .htaccess
在您的 application.rb 配置块中尝试添加:
它应该忽略从请求计算的扩展名,并始终使用它。
您也可以尝试将其与空字符串一起使用。
编辑:实际上这不起作用,因为这仅设置默认值。如果请求有扩展名(在您的情况下,从 :format 得出),它将被使用。
我建议将路线中的 :format 更改为其他内容,rails 不会赋予特殊含义,例如 :fmt。那么 Rails 不应添加扩展名并默认为“.html”。
编辑2:如果你必须使用:format,你可以monkeypatch Rails:
注意我在“除非”之前添加的注释符号。这是覆盖我第一个答案中的默认值的部分。
In your application.rb configuration block try adding:
It should ignore the extension calculated from the request, and always use this.
You could also try using this with an empty string instead.
EDIT: actually this won't work because this only sets a default. If the request has an extension (in your case, concluded from :format) it will be used.
I suggest changing :format in your routes to something else, that rails will not give special meaning to, like :fmt. Then rails should not add the extension and default to '.html'.
EDIT2: If you have to use :format you can monkeypatch Rails:
Notice the comment sign I've added before 'unless'. This is the part that overrides the default from my first answer.