Rails检查“If-Modified-Since”的请求标头

时间:2012-10-11 05:28:23

标签: ruby-on-rails api caching

我正在尝试使用Rails构建一个API,它将检查request的{​​{1}}标头,并仅渲染在该日期之后修改的对象。问题是我试图从控制器中的请求头获取值。

"If-Modified-Since"

从请求标头中提取值的正确方法是什么?

3 个答案:

答案 0 :(得分:5)

首先:If-Modified-Since用于HTTP缓存验证。请不要这样使用。改为使用参数。

要回答您的问题:request.headers[]是访问请求标头的正确方法。作为参考,requestActionDispatch::Request对象。

这里的问题是你如何表达约束。您正在将一个块传递给ActiveRecord的{​​{1}}方法,并且该块没有任何意义(#where?)。您可以将其表达为SQL片段,例如:

Symbol#>(String)

或者,您可以放入Squeel,并写下:

Product.where("updated_at > ?", params[:last_update])

答案 1 :(得分:3)

根据W3规范,使用If-Modified-Since的方法完全有效。 [1]此处的其他响应者说它不标准或会破坏您的缓存是不正确的。它不是非常RESTful,不建议在您的数据中包含状态信息(例如GET参数)。

要回答您的问题,您可以使用stale?生成304(如果尚未修改)或生成实际内容。这是一个例子:

def index
  if_modified_since = request.headers['If-Modified-Since'] || DateTime.new
  @items = Item.where("updated_at > ?", if_modified_since).order(updated_at: :desc)
  if stale?(@items.first)
    render json: @items
  end
end

请注意,这假设@items始终包含一个项目。如果它不总是返回某些东西,你可以根据自己的需要定制它。

答案 2 :(得分:1)

request.if_modified_sincerequest.headers["HTTP_IF_MODIFIED_SINCE"]

请注意,这是标头的非标准用法。它通常是指自从If-Modified-Since中指定的时间以来,页面的任何内容是否已更改,而不是该页面应仅包含已更改的内容。

您可能也对stale?方法感兴趣。