繁体   English   中英

如何在Apache / WSGI下控制Python的标准输出编码

[英]How to control Python's stdout encoding under Apache/WSGI

我正在编写Django应用,它将Unicode stdoutstdout 它可以在开发服务器上完美运行,但是使用Apache和modwsgi时,我得到UnicodeEncodeError: 'ascii' codec can't encode characters ...

因此,stdout编码被强制为ASCII。 我发现了许多解决方案,所有这些解决方案似乎都应该根据文档进行工作,但对我而言却无济于事:

  • 我试过设置PYTHONIOENCODING变量utf-8使用SetEnv指令。

  • 我也试着设置LANGLC_ALLLC_CTYPEen_US.UTF-8使用SetEnvPassEnv

  • 由于我的Apache服务器在systemd下运行,因此我尝试使用服务文件中的Environment=指令设置变量。

  • 最后,我尝试将lang=en_US.UTF-8 locale=en_US.UTF-8WSGIDaemonProcess指令中。

这些变量在环境中可见(例如,在调试模式下的Django错误页面上反映出来),但是仍然会发生错误。

这些东西为什么不起作用,我该怎么办? 在Apache外部可以正常工作的代码中覆盖stdout或手动对所有内容进行编码都不是正确的方法。

该错误发生在普通print语句上。 这是引发错误的整个视图:

def test(request):
    import locale
    print locale.getdefaultlocale()
    print locale.getpreferredencoding()

    s = u'привет'
    print s
    return s

Apache错误日志:

('en_US', 'UTF-8')
UTF-8
Internal Server Error: /app/testview/
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/web/my_site/my_app/views.py", line 964, in test
    print s
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)

当我打印sys.stdout本身时,我看到它实际上是一个mod_wsgi.Log对象。 在WSGI文件中,我要做的记录是:

logging.basicConfig(stream=sys.stderr)

版本:Arch Linux上的Python 2.7.14,Apache 2.4.29,mod_wsgi 4.5.20

前两个不会做任何事情,因为SetEnv仅针对每个请求设置WSGI环境,而不设置过程变量。

在大多数情况下,只要您实际上是在守护程序模式下运行事物,就可以在WSGIDaemonProcess上添加lang / locale。 它不适用于嵌入式模式。

您是否已验证自己实际上是在守护程序模式下运行。

这是更改HTTPD_LANG=${HTTPD_LANG-"en_US.utf8"}的解决方案

$ cat -n /etc/init.d/httpd | grep HTTPD_LANG
    34  HTTPD_LANG=${HTTPD_LANG-"en_US.utf8"}
    59          LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
    85      if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM