【问题标题】:Forcing response charset in CherryPy在 CherryPy 中强制响应字符集
【发布时间】:2016-08-22 01:22:38
【问题描述】:

我想通过修改 Content-Type 标头来指定 HTTP 响应字符集。但是,它不起作用。

这是一个简短的例子:

#coding=utf-8
import cherrypy

class Website:
    @cherrypy.expose()
    def index(self):
        cherrypy.response.headers['Content-Type']='text/plain; charset=gbk'
        return '。。。'.encode('gbk')

cherrypy.quickstart(Website(),'/',{
    '/': {
        'tools.response_headers.on':True,
    }
})

当我访问该页面时,Content-Type 神秘地更改为text/plain;charset=utf-8,导致浏览器中出现 mojibake。

C:\Users\Administrator>ncat 127.0.0.1 8080 -C
GET / HTTP/1.1
Host: 127.0.0.1:8080

HTTP/1.1 200 OK
Server: CherryPy/7.1.0
Content-Length: 6
Content-Type: text/plain;charset=utf-8
Date: Mon, 22 Aug 2016 01:08:13 GMT

。。。^C

CherryPy 似乎会检测内容编码并自动覆盖字符集。如果是这样,我该如何禁用此功能?

【问题讨论】:

    标签: python character-encoding cherrypy


    【解决方案1】:

    好的。通过直接篡改cherrypy.response.header_list解决了这个问题。

    #coding=utf-8
    import cherrypy
    
    def set_content_type():
        header=(b'Content-Type',cherrypy.response._content_type.encode())
    
        for ind,(key,_) in enumerate(cherrypy.response.header_list):
            if key.lower()==b'content-type':
                cherrypy.response.header_list[ind]=header
                break
        else:
            cherrypy.response.header_list.append(header)
    
    cherrypy.tools.set_content_type=cherrypy.Tool('on_end_resource',set_content_type)
    
    class Website:
        @cherrypy.expose()
        @cherrypy.tools.set_content_type()
        def index(self):
            cherrypy.response._content_type='text/plain; charset=gbk'
            return '。。。'.encode('gbk')
    
    cherrypy.quickstart(Website(),'/')
    

    【讨论】:

    • 您应该尝试设置tools.encode.encodingtools.decode.encoding docs.cherrypy.org/en/latest/config.html#environments
    • 嗯,我正在使用的网站是一个文件共享服务器,这意味着编码因文件而异。所以我不能将编码硬编码到cherrypy配置中。
    • Cherrypy 配置可能会在类或处理程序的基础上被覆盖。它不必是全球性的。
    • 编码因请求参数而异。例如,/download?id=1 可能是 UTF-8 编码的,/download?id=2 可能是别的东西。
    • stackoverflow.com/a/38665815/595220 JFYI 您无需额外的钩子/工具即可修改标题
    【解决方案2】:

    我通过设置/操作请求标头属性“Accept-Charset”成功设置了内容类型字符集。

    cherrypy.request.headers["Accept-Charset"] = "ISO-8859-1"
    cherrypy.response.headers["Content-Type"] = "text/xml"
    

    结果:

    >curl -I https://127.0.0.1/url?param=value
    
    HTTP/1.1 200 OK
    Content-Type: text/xml;charset=ISO-8859-1
    Server: CherryPy/18.6.0
    Date: Mon, 10 Aug 2020 11:54:49 GMT
    Content-Length: 288
    Set-Cookie: session_id=d28fa46a1a3d901d9502038255ce869b21add5cc; expires=Mon, 10 Aug 2020 12:54:49 GMT; Max-Age=3600; Path=/
    

    【讨论】:

      猜你喜欢
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      相关资源
      最近更新 更多