• 【玩转Golang】beego下实现martini中的透明式静态文件服务(static folder)效果。


      出于效率等原因,最近将web框架由martini切换为了beego,其他地方都很平顺,只是两个框架的handler签名不一致,需要修改,所以耗时较长,这是预计到的。但是有一个地方没有预计到,也耗费了较多时间,那就是静态文件的服务。

      用过martini的tx都知道,在mairtini中如果我们设置一个目录为静态文件目录,只需添加martini的Static插件,如设置web子目录为应用的静态文件路径:

            m.Use(martini.Static("web"))

      此时,如果我们访问一个url,此url并没有在martini中注册,但是如果位于web目录中,就可以得到响应,例如:

    http://127.0.0.1:8088/ 
    //返回web目录下的index.html
    http://127.0.0.1:8088/ js/jquery.js
    //返回web/js/jquery.js

      但是,切换为beego之后,却没有找到这样的功能。发现beego对于静态文件的支持设计的有点不够友好,比如我进行如下设置

    beego.SetStaticPath("/web", "web")

      这时候访问结果如下

    http://127.0.0.1:8088/ 
    //返回404页面
    http://127.0.0.1:8088/web
    //返回404页面
    http://127.0.0.1:8088/web/index.html
    //返回403 (Forbidden)
    http://127.0.0.1:8088/web/chat.html
    //返回正常
    http://127.0.0.1:8088/web/images/test.png
    //返回正常

      据此结果,有两点不满意:

    1. 必须添加该staticdir 映射的path访问,设置为“/” 无效
    2. 竟然不能返回默认页面!看文档需要设置”beego.DirectoryIndex=true“ ,不是我需要的!

      因此,我着手自己实现该需求。通过学习beego文档,发现可以设置Filter。于是,编写如下代码:

    //main中如下设置filter
    beego.InsertFilter("/*", beego.BeforeRouter, TransparentStatic) .
    .
    . func TransparentStatic(ctx
    *context.Context) { defInd := 0 maxInd := len(defHomes) - 1 orpath := ctx.Request.URL.Path beego.Debug(" in trasparentstatic filter orpath", orpath) if strings.Index(orpath, "api/") >= 0 || strings.Index(orpath, "web/") >= 0 { return } DefaultStartPage: p := orpath if strings.EqualFold(p, "/") { p += defHomes[defInd] defInd++ } ps := strings.Split(p, "/") ps = append([]string{"web"}, ps...) rp := strings.Join(ps, "/") fp := fw.MapPath(rp) beego.Debug("test fp", fp) if !fileutils.Exists(fp) { if defInd > 0 && defInd < maxInd { goto DefaultStartPage } return } else { beego.Debug("found static ", fp) http.ServeFile(ctx.ResponseWriter, ctx.Request, fp) //cannot use Redirect! will lead loop //http.Redirect(ctx.ResponseWriter, ctx.Request, rp, http.StatusFound) return } // }

      运行之后,发现访问服务地址,带不带末尾的"/",都不能返回默认页面,如果明确访问/index.html可以实现访问。后经探索发现,虽然beego说明中说"/*"可以适配所有url,但是实际上不能适配"/",因此需要在注册一个filter到”/":

    beego.InsertFilter("/", beego.BeforeRouter, TransparentStatic) //must has this for default page
    beego.InsertFilter("/*", beego.BeforeRouter, TransparentStatic)

    至此,一切正常了。

  • 相关阅读:
    browserCaps与浏览器功能设置
    roleManager与角色管理授权
    identity与ASP.NET 模拟
    anonymousIdentification 与匿名访问
    authorization与URL授权
    v-loading使用(来自官网介绍)
    8-dentry占用过多内存的分析
    sourceTree使用
    5-Nginx map 使用详解
    11-Sampling Requests with NGINX Conditional Logging
  • 原文地址:https://www.cnblogs.com/dajianshi/p/4261936.html
Copyright © 2020-2023  润新知