我正在尝试使用Rails构建一个API,它将检查request
的{{1}}标头,并仅渲染在该日期之后修改的对象。问题是我试图从控制器中的请求头获取值。
"If-Modified-Since"
从请求标头中提取值的正确方法是什么?
答案 0 :(得分:5)
首先:If-Modified-Since
用于HTTP缓存验证。请不要这样使用。改为使用参数。
要回答您的问题:request.headers[]
是访问请求标头的正确方法。作为参考,request
是ActionDispatch::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_since
或request.headers["HTTP_IF_MODIFIED_SINCE"]
请注意,这是标头的非标准用法。它通常是指自从If-Modified-Since中指定的时间以来,页面的任何内容是否已更改,而不是该页面应仅包含已更改的内容。
您可能也对stale?
方法感兴趣。