要将文件上传到Google存储空间,我将多部分POST请求发送到create_upload_url(redirect_path)返回的网址。 POST请求包括我需要在redirect_path中使用的文件和JSON字符串。
如果JSON字符串具有unicode字符,那么在GAE将多部分POST请求转发给我之后它将被破坏。
发送到上传网址的JSON字符串:
{"subject": "日文", "tag_key": "ahNifnN1aXF1aS1kZXYtMTcwMDAycjkLEgRUZWFtIgtzdWlxdWlfdGVzdAwLEgdUYWdUeXBlGICAgICAgIAKDAsSA1RhZxiAgICAgK6ZCQw"}
GAE之后的JSON字符串将请求转发给redirect_path
{"subject": "=E6=97=A5=E6=96=87", "tag_key": "ahNifnN1aXF1aS1kZXYtMTcwMDAyc=
jkLEgRUZWFtIgtzdWlxdWlfdGVzdAwLEgdUYWdUeXBlGICAgICAgIAKDAsSA1RhZxiAgICAgK6Z=
CQw"}
unicode变得不可读,并且意外插入了'='和'换行符'。
奇怪的是,带有unicode的较短JSON字符串工作正常。
{"subject": "日文", "tag_key": ""}.
其他要点,
问题只发生在生产环境中。我无法在本地开发服务器中重现。
对redirect_path的多部分POST请求没有问题。只有在发布到blobstore.create_upload_url时才会出现此问题。
我正在使用GAE标准环境,Python,Django,Django Rest框架和Postman进行测试。
如果您认为有任何可能的原因,请告诉我。
答案 0 :(得分:1)
您的json字符串正在使用quoted-printable encoding进行编码以进行传输,因为它包含非ascii字符。 Python标准库中的quopri模块提供了处理此问题的工具:
>>> import quopri
>>> foo = '{"subject": "日文", "tag_key": "ahNifnN1aXF1aS1kZXYtMTcwMDAycjkLEgRUZWFtIgtzdWlxdWlfdGVzdAwLEgdUYWdUeXBlGICAgICAgIAKDAsSA1RhZxiAgICAgK6ZCQw"}'
>>> encoded = quopri.encodestring(foo)
>>> print encoded
{"subject": "=E6=97=A5=E6=96=87", "tag_key": "ahNifnN1aXF1aS1kZXYtMTcwMDAyc=
jkLEgRUZWFtIgtzdWlxdWlfdGVzdAwLEgdUYWdUeXBlGICAgICAgIAKDAsSA1RhZxiAgICAgK6Z=
CQw"}
您可以使用quopri.decodestring
解码以获取原始字符串:
>>> print quopri.decodestring(encoded)
{"subject": "日文", "tag_key": "ahNifnN1aXF1aS1kZXYtMTcwMDAycjkLEgRUZWFtIgtzdWlxdWlfdGVzdAwLEgdUYWdUeXBlGICAgICAgIAKDAsSA1RhZxiAgICAgK6ZCQw"}
编码是由json字符串中存在的非ascii字符触发的;正在插入换行符,因为quoted-printable encoding强制执行76个字符的行长度。
您可以通过转义json字符串中的非ascii字符来完全避免此问题 - 例如,Python的json模块执行此操作by default:
如果 ensure_ascii 为true(默认值),则所有非ASCII字符都在 输出使用
\uXXXX
序列进行转义,结果为str 实例仅由ASCII字符组成。
>>> json.dumps({"subject": "日文", "tag_key": "ahNifnN1aXF1aS1kZXYtMTcwMDAycjkLEgRUZWFtIgtzdWlxdWlfdGVzdAwLEgdUYWdUeXBlGICAgICAgIAKDAsSA1RhZxiAgICAgK6ZCQw"})
{
"tag_key": "ahNifnN1aXF1aS1kZXYtMTcwMDAycjkLEgRUZWFtIgtzdWlxdWlfdGVzdAwLEgdUYWdUeXBlGICAgICAgIAKDAsSA1RhZxiAgICAgK6ZCQw",
"subject": "\u65e5\u6587"
}