GAE:Blob上传后,Unicode JSON字符串在多部分帖子中不起作用

时间:2017-06-23 07:21:04

标签: python django google-app-engine unicode google-cloud-storage

要将文件上传到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": ""}.

其他要点,

  1. 问题只发生在生产环境中。我无法在本地开发服务器中重现。

  2. 对redirect_path的多部分POST请求没有问题。只有在发布到blobstore.create_upload_url时才会出现此问题。

  3. 我正在使用GAE标准环境,Python,Django,Django Rest框架和Postman进行测试。

  4. 如果您认为有任何可能的原因,请告诉我。

1 个答案:

答案 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"
}