1

我正在尝试使用 Rails 构建一个 API,它将检查request标头"If-Modified-Since"并仅呈现在该日期之后修改的对象。问题是我试图从控制器中的请求标头中获取值。

# API
def index
   @products = Product.where{updated_at > request.headers["If-Modified-Since"]}
   render "v1/products/index"
end

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

4

3 回答 3

5

第一:If-Modified-Since用于 HTTP 缓存验证。请不要以这种方式使用它。请改用参数。

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

这里的问题是您如何尝试表达约束。您将一个块传递给ActiveRecord's#where方法,而该块没有任何意义(Symbol#>(String)?)。您可以将其表示为 SQL 片段,例如:

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

或者,您可以放入Squeel,然后编写:

Product.where{ updated_at > params[:last_update] }
于 2012-10-11T05:53:19.700 回答
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 始终包含一个项目。如果它并不总是返回某些东西,您可以根据您的需要对其进行定制。

于 2013-11-14T05:31:56.320 回答
1

request.if_modified_since或者request.headers["HTTP_IF_MODIFIED_SINCE"]

请注意,这是标头的非标准用法。一般是指在If-Modified-Since中指定的时间之后,页面的内容是否发生了变化,并不是说页面应该只包含发生变化的内容

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

于 2012-10-11T05:51:17.567 回答