【问题标题】:How to pass unicode values as urlfetch payload?如何将 unicode 值作为 urlfetch 有效负载传递?
【发布时间】:2017-02-25 01:20:47
【问题描述】:

这是我的简化代码:

#coding=utf-8
...

def api_call(method, token, params=[], payload=None):
    ...
    headers = {
        'Content-Type': 'application/json; charset=utf-8'
    }
    try:
        response = urlfetch.Fetch(url, headers=headers, method=urlfetch.POST, payload=payload, deadline=60)
    ...

payload = '{"search":"%s"}' % ('тест') # UNICODE HERE!

result = api_call(method=method, token=MY_TOKEN, payload=payload) 

这段代码适用于非 unicode 字符,但是当使用 unicode 时,我得到:

  File "/Users/me/Documents/Dev/GAE/app.py", line 38, in api_call
    response = urlfetch.Fetch(url, headers=headers, method=urlfetch.POST, payload=payload, deadline=60)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/urlfetch.py", line 271, in fetch
    return rpc.get_result()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result
    return self.__get_result_hook(self)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/urlfetch.py", line 378, in _get_fetch_result
    rpc.check_success()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 579, in check_success
    self.__rpc.CheckSuccess()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_rpc.py", line 157, in _WaitImpl
    self.request, self.response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 201, in MakeSyncCall
    self._MakeRealSyncCall(service, call, request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 219, in _MakeRealSyncCall
    request_pb.set_request(request.Encode())
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/net/proto/ProtocolBuffer.py", line 103, in Encode
    self.Output(e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/net/proto/ProtocolBuffer.py", line 347, in Output
    self.OutputUnchecked(e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/urlfetch_service_pb.py", line 478, in OutputUnchecked
    out.putPrefixedString(self.payload_)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/net/proto/ProtocolBuffer.py", line 607, in putPrefixedString
    v = str(v)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 92-93: ordinal not in range(128)

这里有什么问题?

【问题讨论】:

  • 您不能在没有编码的情况下通过网络连接发送 Unicode 文本。显式编码。
  • @MartijnPieters,谢谢。如果我这样做urllib.quote( u'тест'.encode('utf-8') ),那么我也不会例外,但是第 3 方服务器不理解传递的 url 编码文本。
  • 可能是这样,但尝试发送没有编码的 Unicode 文本不是解决方案。
  • @MartijnPieters,如果我使用 Advanced Rest Client(Chrome 插件)发送相同的数据(没有 url 编码),那么它运行良好。不确定如何调试 ARC 发送的内容 - 它是否对数据进行编码。

标签: python-2.7 google-app-engine unicode


【解决方案1】:

payload = '{"search":"%s"}' % ('тест') # UNICODE HERE!

这不是创建 JSON 序列化对象的好方法。除了字符编码问题之外,如果模板化字符串包含字符串文字中的特殊字符,例如引号或反斜杠,您也会遇到问题。建议使用json模块创建序列化表单,同时兼顾编码:

search = u'тест'
payload = json.dumps({'search': search})

'内容类型': '应用程序/json;字符集=utf-8'

application/json 媒体类型没有 charset 参数;这没有任何作用。 JSON 始终为 UTF,无论如何默认为 UTF-8。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-08
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多