如何在Google App Engine for Python上设置ETag?

如何在Google App Engine for Python上设置ETag?,python,json,google-app-engine,http-headers,Python,Json,Google App Engine,Http Headers,我正在从Google应用程序引擎服务器提供一些JSON内容。我需要为内容提供ETAG,以了解自上次加载数据以来内容是否发生了更改。然后,我的应用程序将删除其旧数据,并使用新的JSON数据填充其视图 self.response.headers['Content-Type'] = "application/json; charset=utf-8" self.response.out.write(json.dumps(to_dict(objects,"content"))) 为响应设

我正在从Google应用程序引擎服务器提供一些JSON内容。我需要为内容提供ETAG,以了解自上次加载数据以来内容是否发生了更改。然后,我的应用程序将删除其旧数据,并使用新的JSON数据填充其视图

    self.response.headers['Content-Type'] = "application/json; charset=utf-8"
    self.response.out.write(json.dumps(to_dict(objects,"content")))

为响应设置ETag的最佳实践是什么?我必须自己计算ETAG吗?或者这是一种让HTTP协议执行此操作的方法?

您必须自己计算e-tag值。电子标签是不透明的字符串,只对应用程序有意义

最佳实践是连接所有确定JSON内容的输入变量(转换为字符串);任何如果更改会导致JSON输出发生更改的内容都应该是其中的一部分。如果这些字符串中有任何不想公开的敏感内容,请改用值的MD5散列

例如,在我管理的CMS应用程序中,首页有以下电子标签:

|531337735|en-us;en;q=0.5|0|Eli Visual Theme|1|943ed3c25e6d44497deb3fe274f98a96||
我们关心的输入变量已与
|
符号连接成一个不透明的值,但它确实表示几个不同的输入值,例如上次修改的时间戳(数字)、浏览器接受的语言标题、当前视觉主题以及从浏览器cookie检索的内部UID如果这些变量中的任何一个发生变化,页面可能会不同,缓存的副本也会过时


请注意,如果没有快速验证的方法,电子标签是无用的。如果没有匹配的请求标头,客户端将把它包含在
中,服务器应该能够从当前变量快速重新计算电子标签标头,并查看该标签是否仍然是当前的。如果重新计算将花费与重新生成相同的时间使用内容体,只需发送
304 Not Modified
响应,而不是
200 OK
响应中的完整JSON正文,即可节省少量带宽。

如果您使用的是webapp2,它可以根据响应体自动添加md5 ETag

self.response.md5_etag()

m=md5.new()json_dumps=json.dumps(helpers.to_dict(object,“content”))m.update(json_dumps)self.response.headers['content-Type']=“application/json;charset=utf-8”self.response.headers['ETag']=m.digest()self.response.out.write(json_dumps)
@Hakonbogen:现在你的电子标签和你的响应一样昂贵,你已经挫败了它的目的。我只使用ETag来验证我是否必须更改磁盘上存储的数据,所以不管它对服务器来说有多贵。@Hakonbogen:所以你只使用电子标签在客户端将响应与磁盘上的值相匹配?然后st将
md5
存储在客户端,并在收到新响应时重新计算。您不需要电子标签,这不是电子标签的目的。在数据存储中保留上次更改的时间戳,并将etag作为时间戳或修订号。遗憾的是,这样的电子标签基本上是无用的,因为您必须重新生成whole响应体重新计算。电子标签的目的是避免仅为了查看响应是否仍然新鲜而这样做。@MartijnPieters删除重新生成响应的需要是有用的,但是减少从服务器发送到客户端的数据也会产生非常大的影响。