Google App Engine 键值错误
我正在写一个谷歌应用引擎的应用程序,但在请求到达时出现了一个键值错误。
从错误追踪信息来看,我只是访问了一些内容,导致了这个键错误。
self.request.headers
完整的代码片段在这里,我只是转发了未修改的请求头。
response = fetch( "%s%s?%s" % (
self.getApiServer() ,
self.request.path.replace("/twitter/", ""),
self.request.query_string
),
self.request.body,
method,
self.request.headers,
)
处理请求的GET方法调用了proxy()。
# handle http get
def get(self, *args):
parameters = self.convertParameters(self.request.query_string)
# self.prepareHeader("GET", parameters)
self.request.query_string = "&".join("%s=%s" % (quote(key) , quote(value)) for key, value in parameters.items())
self.proxy(GET, *args)
def convertParameters(self, source):
parameters = {}
for pairs in source.split("&"):
item = pairs.split("=")
if len(item) == 2:
parameters[item[0]] = unquote(item[1])
return parameters
错误的追踪信息如下:
'CONTENT_TYPE'
Traceback (most recent call last):
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 513, in __call__
handler.post(*groups)
File "/base/data/home/apps/waytosing/1.342850593213842824/com/blogspot/zizon/twitter/RestApiProxy.py", line 67, in post
self.proxy(POST, *args)
File "/base/data/home/apps/waytosing/1.342850593213842824/com/blogspot/zizon/twitter/RestApiProxy.py", line 47, in proxy
self.request.headers,
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py", line 240, in fetch
allow_truncated, follow_redirects)
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/urlfetch.py", line 280, in make_fetch_call
for key, value in headers.iteritems():
File "/base/python_runtime/python_dist/lib/python2.5/UserDict.py", line 106, in iteritems
yield (k, self[k])
File "/base/python_runtime/python_lib/versions/1/webob/datastruct.py", line 40, in __getitem__
return self.environ[self._trans_name(item)]
KeyError: 'CONTENT_TYPE'
你知道为什么会发生这个错误吗?还是说这是一个已知的bug?
4 个回答
这是一个已知的问题,详细信息可以在这里找到:http://code.google.com/p/googleappengine/issues/detail?id=3427。另外,这里有一些可能的解决办法:http://code.google.com/p/googleappengine/issues/detail?id=2040
我对这个问题有一些观察:当内容类型是 application/x-www-form-urlencoded 而且 POST 数据为空(比如使用 jquery.ajax 的 GET 请求,或者 Twitter 的收藏和转发 API 等等),Google App Engine 会忽略这个内容类型。你可以在 urlfetch 之前添加:
self.request.headers.update({'content-type':'application/x-www-form-urlencoded'})
。
这看起来有点奇怪。文档提到,响应的“头部对象在你尝试获取或删除一个不存在的键时不会报错。获取一个不存在的头部只会返回 None”。不过从请求的文档来看,request.headers 是否也是这种类型的对象并不清楚,即使它们是普通的字典,iteritems
似乎也有点问题。所以这可能是个bug。
在调用 fetch
之前,检查一下 self.request.headers
可能是个好主意,看看 1) 它的实际类型是什么,2) 它的键都有哪些,3) 如果尝试获取 self.request.headers['CONTENT_TYPE']
时是否会报错。
不过,如果你只是想解决问题并继续前进,可以尝试像这样绕过它:
if 'CONTENT_TYPE' not in self.request.headers:
self.request.headers['CONTENT_TYPE'] = None
(我建议把它设置为 None,因为这就是一个响应头对象在键不存在时应该返回的结果)