在javascript中对unicode字符串进行编码之后,如何在Python中对其进行解码?

在javascript中对unicode字符串进行编码之后,如何在Python中对其进行解码?,javascript,python,google-app-engine,Javascript,Python,Google App Engine,平台:应用程序引擎 框架:webapp/CGI/WSGI 在我的客户端(JS)上,我通过将URL与unicode字符串连接来构造URL: http://www.foo.com/地震 然后我调用encodeURI获取 http://www.foo.com/%E5%9C%B0%E9%9C%87 我把它放在一个HTML表单值中 表单被提交到PayPal,在那里我将编码设置为“utf-8” 然后,贝宝(通过IPN)在上述URL上发出post请求 在我的服务器端,WSGIApplication尝试使用

平台:应用程序引擎 框架:webapp/CGI/WSGI

在我的客户端(JS)上,我通过将URL与unicode字符串连接来构造URL:

http://www.foo.com/地震
然后我调用encodeURI获取

http://www.foo.com/%E5%9C%B0%E9%9C%87
我把它放在一个HTML表单值中

表单被提交到PayPal,在那里我将编码设置为“utf-8”

然后,贝宝(通过IPN)在上述URL上发出post请求

在我的服务器端,WSGIApplication尝试使用我定义的正则表达式提取unicode字符串:

(r'/paypal-listener/(.+?)', c.PayPalIPNListener)
我会打电话试着解码

query = unquote_plus(query).decode('utf-8')
(或一个变体)但我会得到错误

/贝宝监听器/%E5%9C%B0%E9%9C%87

。。。(ommited)

“ascii”编解码器无法对字符进行编码 在位置0-1:序号不在 射程(128)

(第一行是请求URL)


当我检查
query
的长度时,python说它的长度为18,这向我表明“%E5%9C%B0%E9%9C%87”还没有被编码

假设HTML页面是用utf-8编码的,如果框架对URL进行解码,那么它应该是一个简单的
path.decode('utf-8')

如果没有,您可以使用:

  • 如果URL是
    http://www.foo.com/地震
  • urllib.unquote\u plus(path).decode('utf-8')
    如果您谈论的是通过AJAX或HTML发送的参数
(见附件)

编辑:如果您仍有问题,请向我们提供以下信息,以帮助我们跟踪此问题:

  • 您在google app engine内部使用的web框架,例如Django、WebOb、CGI等

  • 如何在应用程序中获取URL(如果可以,请添加简短的代码示例)

  • 添加时的报告(url)http://www.foo.com/地震作为URL

  • 尝试将此添加为URL并发布
    repr(URL)
    ,这样我们可以确保服务器不会将字符解码为或:

编辑2:将其视为实际URL(不在查询部分,即不
http://www.foo.com/?param=%E5%9C%B0%E9%9C%87
),正在执行


可能是安全的。如果您正在解码实际的URL,则它应该是
unquote
,而不是
unquote\u plus
。我不知道为什么google会将URL作为
unicode
对象传递,但我怀疑传递给应用程序的实际URL是否会使用
windows-1252
等进行解码。我有点担心,因为我认为它对查询的解码不正确(即传递给
GET
POST
的参数)但从外观上看,它似乎没有做到这一点。

通常服务器端语言中有一个函数来解码URL,Python中也可能有一个。您还可以在您的案例中使用javascript的功能。

aaah,可怕的

“ascii”编解码器无法对位置中的字符进行编码。。。序号不在范围内

错误。在python中处理日语等语言时不可避免

在这种情况下,这不是url编码/解码问题。您的数据很可能已经解码并准备就绪

我会尝试摆脱“解码”的呼叫,看看会发生什么。如果你收到垃圾,但没有错误,这可能意味着人们正在用另一种可爱的日本特定编码向你发送数据:eucjp、iso-2022-jp、shift jis,或者甚至是难以捉摸的iso-2022-jp-ext,这在当今的野外是很少见的。但后一种情况似乎不太可能发生

编辑:id还可以查看以下内容以供参考: 在这种情况下不喜欢unicode字符串。将其传递给字节字符串,然后解码以获得unicode

这项工作:

>>> u = u'http://www.foo.com/%E5%9C%B0%E9%9C%87'
>>> print urllib.unquote(u.encode('ascii'))
http://www.foo.com/地震
>>> print urllib.unquote(u.encode('ascii')).decode('utf-8')
http://www.foo.com/地震
这并不是(另请参见):

解码已使用unicode的字符串不起作用:

>>> print urllib.unquote(u).decode('utf-8')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File ".../lib/python2.6/encodings/utf_8.py", line
16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 19-24: o
rdinal not in range(128)
>>打印urlib.unquote(u).decode('utf-8')
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“../lib/python2.6/encodings/utf_8.py”,第行
16,在解码中
返回编解码器.utf_8_解码(输入,错误,真)
UnicodeEncodeError:“ascii”编解码器无法对位置19-24:o中的字符进行编码
rdinal不在范围内(128)

原则上,这应该是可行的:

>>> urllib.unquote_plus('http://www.foo.com/%E5%9C%B0%E9%9C%87').decode('utf-8')
u'http://www.foo.com/\u5730\u9707'
但是,请注意:

  • 用于
    应用程序/x-form-www-urlencoded
    数据,如已发布的表单和查询字符串参数。在URL的路径部分,
    +
    表示文字加号,而不是空格,因此您应该在此处使用plain

  • 一般来说,您不应该取消引用整个URL。URL组件中具有特殊含义的字符将丢失。您应该将URL拆分为多个部分,获取您感兴趣的单个路径名组件(
    %E5%9C%B0%E9%9C%87
    ),然后将其解压缩

  • (如果要将URI完全转换为类似IRI的
    http://www.foo.com/地震事情有点复杂。只有IRI的路径/查询/片段部分是UTF-8-%编码的;域名使用古怪的“Punycode”IDN方案在Unicode和字节之间映射。)

    这将在我的python服务器端接收

    您的服务器端到底是什么?服务器、网关、框架?如何获取
    url
    变量

    您似乎得到了一个,这是关于
    unquote
    函数输入中意外的非ASCII字符,根本不是解码问题。因此,我建议有人已经将URL的路径部分解码为某种Unicode字符串。让我们看看该变量的
    repr

    不幸的是,一些web服务器存在一些严重问题,这使得在URL的路径名部分使用Unicode非常不可靠,不仅在Python中,而且在一般情况下

    主要问题是
    PATH\u INFO
    变量是由CGI规范定义的,并且
    >>> print urllib.unquote(u)
    http://www.foo.com/å °é  
    
    >>> print urllib.unquote(u).decode('utf-8')
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File ".../lib/python2.6/encodings/utf_8.py", line
    16, in decode
        return codecs.utf_8_decode(input, errors, True)
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 19-24: o
    rdinal not in range(128)
    
    >>> urllib.unquote_plus('http://www.foo.com/%E5%9C%B0%E9%9C%87').decode('utf-8')
    u'http://www.foo.com/\u5730\u9707'
    
      var uri = "https://rasamarasa.com/service/catering/ගාල්ල-Galle";
      var uri_enc = encodeURIComponent(uri);
      var uri_dec = decodeURIComponent(uri_enc);
      var res = "Encoded URI: " + uri_enc + "<br>" + "Decoded URI: " + uri_dec;
      document.getElementById("demo").innerHTML = res;