我的第一个想法是在过滤器中获取响应正文,然后使用像 tdewolff/minify 这样的缩小库并写入响应,但我找不到获取响应正文的方法。有没有更好的解决方案?
问问题
266 次
1 回答
0
通过查看文档,过滤器似乎可以访问Controller
包含Response
. 这个响应包含Out
一个 ResponseWriter(因此也是一个 io.Writer)。我们只需要替换 Write 方法即可将写入重定向到压缩器,然后再写入响应写入器。为此,我们需要使用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。确保获得正确的 mimetype(通过扩展?)或直接调用适当的 minify 函数。
于 2015-10-11T23:02:48.747 回答