【问题标题】:Prepend BOM to XML response from Django将 BOM 附加到来自 Django 的 XML 响应
【发布时间】:2009-09-14 21:03:31
【问题描述】:

我使用 Django 的 render_to_response 返回一个 XML 文档。这个特定的 XML 文档适用于基于 Flash 的图表库。该库要求 XML 文档以 BOM(字节顺序标记)开头。如何让 Django 将 BOM 预先添加到响应中?

它可以将 BOM 插入模板,但不方便,因为 Emacs 每次编辑文件时都会将其删除。

我尝试如下重写render_to_response,但由于 BOM 是 UTF-8 编码而失败:

def render_to_response(*args, **kwargs):
    bom = kwargs.pop('bom', False)
    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
    s = django.template.loader.render_to_string(*args, **kwargs)
    if bom:
        s = u'\xef\xbb\xbf' + s
    return HttpResponse(s, **httpresponse_kwargs)

【问题讨论】:

    标签: xml django byte-order-mark


    【解决方案1】:

    您并不是真的在谈论 BOM(字节顺序标记),因为 UTF-8 没有 BOM。从您的示例代码中,库希望文本有 3 个垃圾字节,因为某些莫名其妙的原因。

    您的代码几乎是正确的,但您必须将字节添加为 bytes,而不是字符。试试这个:

    def render_to_response(*args, **kwargs):
        bom = kwargs.pop('bom', False)
        httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
        s = django.template.loader.render_to_string(*args, **kwargs)
        if bom:
            s = '\xef\xbb\xbf' + s.encode("utf-8")
        return HttpResponse(s, **httpresponse_kwargs)
    

    【讨论】:

    • 我想它我们正在谈论的UTF-8。一些(通常是微软衍生的)软件喜欢将 BOM 放在 UTF-8 中,尽管它们毫无意义且有害。一个需要一个 XML 阅读器,但是,它坏了,根本不是一个真正的 XML 阅读器。
    • 在 UTF-8 中没有 BOM 这样的东西,因为 UTF-8 没有字节顺序。如果某些软件依赖于文件中存在的随机垃圾字节,那就不同了。
    • @Vebjorn:我已经更新了答案以反映您编辑的问题。您的代码几乎已经正确。
    【解决方案2】:

    此解决方案基于 John Millikin 答案的先前版本,比我接受的解决方案更复杂,但为了完整起见,我将其包含在此处。首先,定义一个中间件类:

    class AddBOMMiddleware(object):
        def process_response(self, request, response):
            import codecs
            if getattr(response, 'bom', False):
                response.content = codecs.BOM_UTF8 + response.content
            return response
    

    在您的设置中将其名称添加到 MIDDLEWARE_CLASSES。然后重新定义render_to_response

    def render_to_response(*args, **kwargs):
        bom = kwargs.pop('bom', False)
        httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
        rendered = django.template.loader.render_to_string(*args, **kwargs)
        response = django.http.HttpResponse(rendered, **httpresponse_kwargs)
        if bom:
            response.bom = True
        return response
    

    现在,您可以通过 render_to_response("foo.xml", mimetype="text/xml", bom=True) 将 BOM 预先添加到特定响应中。

    【讨论】:

      【解决方案3】:

      最简单的方法可能是将 Emacs 配置为不删除 BOM。

      但是 render_to_response 并不是一个复杂的函数。基本上是:

      def render_to_response(*args, **kwargs):
          return HttpResponse(loader.render_to_string(*args, **kwargs))
      

      您可以轻松调用 render_to_string 并添加 BOM。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-02
        • 2017-05-04
        • 2021-12-07
        • 2022-01-08
        相关资源
        最近更新 更多