我的第一个想法是将响应主体放入过滤器中,然后使用诸如tdewolff / minify之类的minify库之一并写入响应,但是我找不到找到响应主体的方法。
有没有更好的解决方案?

最佳答案

通过查看文档,过滤器似乎可以访问Controller类型,其中包含Response。此响应包含Out,它是ResponseWriter(因此也是io.Writer)。我们只需要替换Write方法即可将写入重定向到Minifier,然后再将其写入响应编写器。为此,我们需要使用io.Pipe和一个goroutine。

type MinifyResponseWriter struct {
    http.ResponseWriter
    io.Writer
}

func (f MinifyResponseWriter) Write(b []byte) (int, error) {
    return f.Writer.Write(b)
}

func MinifyFilter(c *Controller, fc []Filter) {
    pr, pw := io.Pipe()
    go func(w io.Writer) {
        m := minify.New()
        m.AddFunc("text/css", css.Minify)
        m.AddFunc("text/html", html.Minify)
        m.AddFunc("text/javascript", js.Minify)
        m.AddFunc("image/svg+xml", svg.Minify)
        m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)
        m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), xml.Minify)

        if err := m.Minify("mimetype", w, pr); err != nil {
            panic(err)
        }
    }(c.Response.Out)
    c.Response.Out = MinifyResponseWriter{c.Response.Out, pw}
}

遵循这些原则(未经测试)。在这里,我们接收传入的io.Writer(这是ResponseWriter的一部分),并在其周围包装一个结构。它保留了响应编写器的原始方法,但是重写了Write方法,以将其替换为PipeWriter。这意味着对新响应编写器的任何写操作都将传递给PipeWriter,后者与PipeReader耦合。缩小从该读取器读取的内容并写入原始响应编写器。

因为我们更改了c.Response.Out的值,所以我们需要将其显式传递给goroutine。确保获得正确的模仿类型(通过扩展名?)或直接调用适当的minify函数。

关于go - 如何使用Revel框架执行HTML Minify,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33067616/

10-12 22:35