批量删除联系人时遇到“If-Match或If-None-Match头部或etag属性要求”错误

11 投票
3 回答
2323 浏览
提问于 2025-04-18 06:04

我正在使用 gdata 这个Python库来批量删除联系人,但总是出现“需要 If-Match 或 If-None-Match 头或条目 etag 属性”的错误。

我觉得问题是从我在控制台里启用联系人API开始的(在几天前其实并不需要这样做?*)。

编辑:

实际上,这个问题在更新和删除操作时都会出现。批量插入是没问题的。

我尝试指定 If-Match 头,但还是失败了:

custom_headers = atom.client.CustomHeaders(**{'If-Match': '*'})
request_feed = gdata.contacts.data.ContactsFeed()
request_feed.AddDelete(entry=contact, batch_id_string='delete')
response_feed = self.gd_client.ExecuteBatch(
        request_feed,
        'https://www.google.com/m8/feeds/contacts/default/full/batch',
        custom_headers=custom_headers
)

我还在项目页面上创建了一个问题单,但我怀疑那边会有人关注。

编辑 2:

使用 Batch 方法并设置 force=True(这只是添加了 If-Match: * 头)结果也是一样。

response_feed = self.gd_client.Batch(
    request_feed,
    uri='https://www.google.com/m8/feeds/contacts/default/full/batch',
    force=True
)

* 有人能确认一下吗?我之前从来不需要在控制台里启用它,我的应用程序也能正常使用联系人API,我相信之前甚至没有这个选项。昨天看到这个我还挺惊讶的。

3 个回答

0

你还可以指定etag属性来解决这个问题。这在批量请求的数据中是有效的:

  <entry   gd:etag="*"  >
     <batch:id>delete</batch:id>
     <batch:operation type="delete"/>
     <id> urlAsId </id>
  </entry>
1

原帖中提到的那个问题单有了一些更新的信息,还有一个临时的解决办法,可以让批量删除成功。目前对我来说这个办法是有效的!

http://code.google.com/p/gdata-python-client/issues/detail?id=700

4

这里是从Google代码问题中复制的答案。

简单来说,你需要对客户端的Post方法进行一些调整,以便稍微修改一下请求的内容。下面是一个方法,可以在不直接改动库的源代码的情况下做到这一点:

def patched_post(client, entry, uri, auth_token=None, converter=None, desired_class=None, **kwargs):
    if converter is None and desired_class is None:
        desired_class = entry.__class__
    http_request = atom.http_core.HttpRequest()
    entry_string = entry.to_string(gdata.client.get_xml_version(client.api_version))
    entry_string = entry_string.replace('ns1', 'gd')  # where the magic happens
    http_request.add_body_part(
        entry_string,
        'application/atom+xml')
    return client.request(method='POST', uri=uri, auth_token=auth_token,
                          http_request=http_request, converter=converter,
                          desired_class=desired_class, **kwargs)

# when it comes time to do a batched delete/update,
# instead of calling client.ExecuteBatch, instead directly call patched_post
patched_post(client_instance, entry_feed, 'https://www.google.com/m8/feeds/contacts/default/full/batch')

撰写回答