当前位置: 首页 > 面试题库 >

在Python 3 CGI脚本中设置编码

井镜
2023-03-14
问题内容

在编写 Python 3.1 CGI脚本时,我遇到了可怕的UnicodeDecodeErrors。但是,在命令行上运行脚本时,一切正常。

似乎使用open()print()的返回值locale.getpreferredencoding()知道默认使用哪种编码。在命令行上运行时,该值应为’UTF-8’。但是,当通过浏览器运行脚本时,编码神秘地重新定义为“
ANSI_X3.4-1968”,这似乎只是纯ASCII的奇特名称。

我现在需要知道如何在所有情况下都以’utf-8’作为默认编码来运行cgi脚本。我的设置是Debian Linux上的Python
3.1.3和Apache2。系统范围的语言环境是en_GB.utf-8。


问题答案:

为后来者回答这个问题,是因为我认为发布的答案并不能解决问题的根源,因为在CGI上下文中缺少语言环境环境变量。我正在使用Python 3.2。

  1. open()以文本(字符串)或二进制(字节)模式打开文件对象以进行读取和/或写入;在文本模式下,可以在调用中指定用于编码写入文件的字符串以及解码从文件读取的字节的编码;如果不是,则由locale.getpreferredencoding()确定,在Linux上,locale.getpreferredencoding()使用您的语言环境设置中的编码,通常为utf-8(例如LANG = en_US.UTF-8)

    >>> f = open('foo', 'w')         # open file for writing in text mode
    

    f.encoding
    ‘UTF-8’ # encoding is from the environment
    f.write(‘€’) # write a Unicode string
    1
    f.close()
    exit()
    user@host:~$ hd foo
    00000000 e2 82 ac |…| # data is UTF-8 encoded

  2. sys.stdout实际上是一个打开的文件,可以使用基于locale.getpreferredencoding()的编码以文本模式写入。您可以向它写字符串,然后根据sys.stdout的编码将它们编码为字节;默认情况下,print()写入sys.stdout-print()本身没有编码,而是它写入的文件具有编码;

    >>> sys.stdout.encoding
    

    ‘UTF-8’ # encoding is from the environment

    exit()
    user@host:~$ python3 -c ‘print(“€”)’ > foo
    user@host:~$ hd foo
    00000000 e2 82 ac 0a |....| # data is UTF-8 encoded; \n is from print()

; 您不能将字节写入sys.stdout-为此使用sys.stdout.buffer.write();
如果尝试使用sys.stdout.write()将字节写入sys.stdout,则它将返回错误,如果尝试使用print(),则print()会将字节对象简单地转换为字符串对象和转义符像这样的序列\xff将被视为四个字符\,x,f,f

    user@host:~$ python3 -c 'print(b"\xe2\xf82\xac")' > foo
user@host:~$ hd foo
00000000  62 27 5c 78 65 32 5c 78  66 38 32 5c 78 61 63 27  |b'\xe2\xf82\xac'|
00000010  0a                                                |.|
  1. 在CGI脚本中,您需要写入sys.stdout,并且可以使用print()来完成此操作;但是Apache中的CGI脚本过程没有语言环境设置-它们不属于CGI规范;因此sys.stdout编码默认为ANSI_X3.4-1968-换句话说,是ASCII;如果您尝试将包含非ASCII字符的字符串print()传送到sys.stdout,则会收到“ UnicodeEncodeError:’ascii’编解码器无法编码字符…:序数不在范围内(128)”

  2. 一个简单的解决方案是使用服务器或虚拟主机配置中的Apache的mod_env PassEnv命令将Apache进程的LANG环境变量传递到CGI脚本。在Debian / Ubuntu上,确保在/ etc / apache2 / envvars中取消注释“。/ etc / default / locale”行,以便Apache以系统默认语言环境而不是C(Posix)语言环境(也是ASCII)运行编码);以下CGI脚本应在Python 3.2中正确运行:

    #!/usr/bin/env python3
    

    import sys
    print(‘Content-Type: text/html; charset=utf-8’)
    print()
    print(‘

    ‘ + sys.stdout.encoding + ‘
    h€lló wörld‘)



 类似资料:
  • 我在谷歌上研究了我的许多问题,但没有找到任何能提供直接答案的东西。我正在设置代码电子邮件一个表一次(或多次)。我无法设置收件人的电子邮件地址。我需要脚本为数据范围()中的每个地址发出一封电子邮件。 我很遗憾,由于隐私原因,我不能分享整个脚本。(从积极的方面来说,除了这个以外,其他的东西都起作用了。) 要获得“gmailapp.sendeMail”语句可用的一个(或多个)电子邮件地址,需要做什么?无

  • 问题内容: 我正在将csh脚本转换为python脚本。该脚本调用一个占用大量内存的可执行文件,该文件需要非常大的堆栈,因此csh脚本将stacksize设置为无限制: 当我尝试在python中重现此脚本时,我会使用,以非常幼稚的方式执行它们,例如: 但是我不知道如何告诉操作系统以不受限制的堆栈大小运行这些可执行文件。有没有办法为python脚本中的调用指定stacksize?我应该使用一些底层系统

  • 问题内容: 我知道如何在/ etc / profile和环境变量中进行设置。 但是,如果我想在脚本中进行设置怎么办?是导入os,sys吗?我该怎么做? 问题答案: 您没有设置,而是向中添加条目。这是应该在其中搜索Python软件包的目录列表,因此您只需将目录追加到该列表即可。 实际上,是通过分割路径分隔符上的值来初始化的(在类似Linux的系统上,在Windows上)。 您也可以使用来添加目录,该

  • 我试图在EditText中设置文本,但它说: 我的代码如下: 不要说用< code>setText,因为我用的是kotlin,不是Java。

  • 问题内容: 我有一个bash脚本,用于设置环境变量并运行命令 现在,我想使用python代替bash,因为我想计算传递给命令的一些参数。 我试过了 和 其次是 但由于未设置LD_LIBRARY_PATH,因此程序总是放弃。 我怎样才能解决这个问题? 感谢帮助! (如果我在调用python脚本之前导出LD_LIBRARY_PATH,则一切正常,但我希望python确定路径并将环境变量设置为正确的值)

  • 测验sh包含: 我设置测试。sh至chmod 777 我用两个参数开始脚本: 然后我通过键入以下内容进行测试: 结果: 我做错了什么?