我尝试使用以下HTML表单将blob上传到Google App Engine的blobstore:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
</head>
<body>
<form id=upload action={{upload_url}} method=post enctype=multipart/form-data>
Name: <input type=text name=name>
Your photo: <input type=file name=image required=required><br><br>
<input type=submit value=submit>
</form>
</body>
</html>
模板变量{{upload_url}}的值由服务器端的upload_url = blobstore.create_upload_url('/upload')
获取。后处理脚本如下:
class Test(ndb.Model):
name = StringProperty()
image = StringProperty()
test = Test()
test.name = self.request.get('name')
image = self.get_uploads('image')[0]
test.image = str(image.key())
test.put()
通常,name
字段将填充非英文字符(例如,中文)。以上程序在我的本地SDK上运行正常。但是,当程序在Google App Engine上运行时,name
编码错误。那么问题是什么?
答案 0 :(得分:1)
您不必在元标记参数前加注引号:<meta charset="UTF-8">
?另外,请尝试:<meta http-equiv="content-type" content="text/html; charset=utf-8" />
。并且,请确保以UTF-8编码保存模板的文本文档。
答案 1 :(得分:1)
多年来刚刚发现这是一个老bug,请参阅here。有两种解决方案:
(1)将以下语句添加到app.yaml:
libraries:
- name: webob
version: "1.2.3"
(2)使用以下内容添加文件appengine_config.yaml:
# -*- coding: utf-8 -*-
from webob import multidict
def from_fieldstorage(cls, fs):
"""Create a dict from a cgi.FieldStorage instance.
See this for more details:
http://code.google.com/p/googleappengine/issues/detail?id=2749
"""
import base64
import quopri
obj = cls()
if fs.list:
# fs.list can be None when there's nothing to parse
for field in fs.list:
if field.filename:
obj.add(field.name, field)
else:
# first, set a common charset to utf-8.
common_charset = 'utf-8'
# second, check Content-Transfer-Encoding and decode
# the value appropriately
field_value = field.value
transfer_encoding = field.headers.get('Content-Transfer-Encoding', None)
if transfer_encoding == 'base64':
field_value = base64.b64decode(field_value)
if transfer_encoding == 'quoted-printable':
field_value = quopri.decodestring(field_value)
if field.type_options.has_key('charset') and field.type_options['charset'] != common_charset:
# decode with a charset specified in each
# multipart, and then encode it again with a
# charset specified in top level FieldStorage
field_value = field_value.decode(field.type_options['charset']).encode(common_charset)
# TODO: Should we take care of field.name here?
obj.add(field.name, field_value)
return obj
multidict.MultiDict.from_fieldstorage = classmethod(from_fieldstorage)