新闻中心
使用 Go 的 FileServer 安全地提供静态文件

本文介绍了如何使用 Go 语言的 net/http 包中的 FileServer 函数来安全地提供静态文件,特别是如何在只允许客户端访问特定文件(例如 index.html)的同时,保护其他文件(例如 J*aScript 文件)不被直接访问。文章提供了两种实现方法:使用中间件包装 FileServer 和自定义 http.FileSystem 接口。
在使用 Go 构建 Web 应用时,经常需要提供静态文件,例如 HTML、CSS、J*aScript 和图片。net/http 包中的 FileServer 函数提供了一种简单的方式来实现这个功能。然而,默认情况下,FileServer 会暴露指定目录下的所有文件,这可能带来安全风险。例如,你可能希望只允许用户访问 index.html,而阻止直接访问 J*aScript 文件。本文将介绍两种方法来解决这个问题。
方法一:使用中间件过滤文件
第一种方法是使用中间件来包装 FileServer,通过中间件来过滤客户端的请求,只允许访问特定类型的文件。下面是一个示例代码:
package main
import (
"log"
"net/http"
"path/filepath"
)
// GlobFilterHandler 是一个中间件,用于过滤文件,只允许访问符合指定模式的文件。
func GlobFilterHandler(h http.Handler, pattern string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
fileName := filepath.Base(path)
ok, err := filepath.Match(pattern, fileName)
if err != nil {
log.Println("Error in pattern match:", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError) // 更加友好的错误提示
return
}
if !ok {
http.NotFound(w, r)
return
}
h.ServeHTTP(w, r)
})
}
func main() {
// 假设静态文件位于 /tmp/dtest 目录
fileHandler := http.FileServer(http.Dir("/tmp/dtest"))
// 只允许访问 *.js 文件
wrappedHandler := GlobFilterHandler(fileHandler, "*.js")
// 将处理程序注册到服务器
http.Handle("/", wrappedHandler) // 注意这里需要指定路由
// 启动服务器
log.Fatal(http.ListenAndServe(":8080", nil))
}代码解释:
- GlobFilterHandler 函数接收一个 http.Handler 和一个模式字符串作为参数,返回一个新的 http.Handler。
- 新的 http.Handler 会检查请求的 URL 路径,提取文件名,并使用 filepath.Match 函数来判断文件名是否符合指定的模式。
- 如果文件名不符合模式,或者匹配过程中发生错误,则返回 404 Not Found 错误。
- 如果文件名符合模式,则调用原始的 http.Handler 来处理请求。
使用方法:
- 将上述代码保存为 main.go 文件。
- 创建一个名为 /tmp/dtest 的目录,并在该目录下创建一些文件,例如 index.html 和 script.js。
- 运行 go run main.go 命令启动服务器。
- 在浏览器中访问 http://localhost:8080/script.js 可以正常访问,访问 http://localhost:8080/index.html 会返回 404 Not Found 错误。
注意事项:
生活同城信息网系统
fankuan8生活同城信息网系统 v1206采用主流的Asp+Access开发设计,网站美工设计方面更大气,漂亮!网站浏览器兼容性也比较好,网站功能方面的细节方面十分强大。 网站程序的几大特点: 1.全站页面实行了伪静态化,各类型网站服务器的伪静态文件都已近处理好了,无需自己再做伪静态出来。 2.网站前台开始使用了fankuan8独立开发的互助链系统,开始使用时,在网站底部点击链接根据提示马上
0
查看详情
- 这个示例只允许访问 .js 文件。你可以根据需要修改模式字符串来允许访问其他类型的文件。
- 需要注意路由的设置,确保中间件能够正确地拦截请求。
方法二:自定义 http.FileSystem 接口
第二种方法是自定义 http.FileSystem 接口,并实现自己的文件访问控制逻辑。下面是一个示例代码:
package main import ("fmt" "log" "net/http" "path/filepath" ) // GlobDir 是一个自定义的 http.FileSystem 实现,用于过滤文件,只允许访问符合指定模式的文件。 type GlobDir struct { Dir http.Dir Pattern string } // Open 方法实现了 http.FileSystem 接口,用于打开文件。 func (d GlobDir) Open(name string) (http.File, error) { baseName := filepath.Base(name) ok, err := filepath.Match(d.Pattern, baseName) if err != nil { return nil, err } if !ok { return nil, fmt.Errorf("%s not match GlobDir pattern.", baseName) } return d.Dir.Open(name) } func main() { // 假设静态文件位于 /tmp/dtest 目录 fileHandler := http.FileServer(GlobDir{ Dir: http.Dir("/tmp/dtest"), Pattern: "*.js", }) // 将处理程序注册到服务器 http.Handle("/", fileHandler) // 注意这里需要指定路由 // 启动服务器 log.Fatal(http.ListenAndServe(":8080", nil)) }
代码解释:
- GlobDir 结构体实现了 http.FileSystem 接口,包含一个 http.Dir 类型的成员和一个模式字符串。
- Open 方法是 http.FileSystem 接口的必须实现的方法,用于打开文件。
- Open 方法首先提取文件名,并使用 filepath.Match 函数来判断文件名是否符合指定的模式。
- 如果文件名不符合模式,则返回一个错误。
- 如果文件名符合模式,则调用原始的 http.Dir 的 Open 方法来打开文件。
使用方法:
- 将上述代码保存为 main.go 文件。
- 创建一个名为 /tmp/dtest 的目录,并在该目录下创建一些文件,例如 index.html 和 script.js。
- 运行 go run main.go 命令启动服务器。
- 在浏览器中访问 http://localhost:8080/script.js 可以正常访问,访问 http://localhost:8080/index.html 会返回一个错误。
注意事项:
- 这个示例只允许访问 .js 文件。你可以根据需要修改模式字符串来允许访问其他类型的文件。
- 自定义 http.FileSystem 接口可以提供更灵活的文件访问控制逻辑。
总结
本文介绍了两种使用 Go 的 FileServer 安全地提供静态文件的方法:使用中间件过滤文件和自定义 http.FileSystem 接口。你可以根据实际需求选择合适的方法。使用中间件的方法更加简单,但灵活性稍差。自定义 http.FileSystem 接口的方法更加灵活,但实现起来稍微复杂一些。无论选择哪种方法,都需要注意文件访问控制,确保Web应用的安全。
以上就是使用 Go 的 FileServer 安全地提供静态文件的详细内容,更多请关注其它相关文章!
# 两种
# 服装推广营销策略的意义
# 网站关键词 排名怎么看
# 网站推广和内容哪个重要
# seo优化服务公司推荐
# 益阳网站建设在线咨询
# 桂林互联网网络推广营销模式
# 大庆网站建设知识框架图
# 甘南网站推广多少钱
# 美容产品网站建设流程
# 宁波本地网站建设
# 来安
# 不符合
# 并在
# 访问控制
# css
# 你可以
# 同城
# 是一个
# 只允许
# 自定义
# 路由
# ai
# app
# 浏览器
# go
# js
# html
# java
# javascript
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
解决Django多数据库/多Schema环境下外键迁移问题
AO3官方镜像站点汇总 AO3同人作品网页版直达链接
windows10怎么查看本机ip_windows10命令提示符ipconfig使用
微信网页版登录教程_微信网页版登录入口在哪
京东京造J1和网易云音乐氧气真无线有什么不同_国产电商蓝牙耳机音质对比
漫蛙manwa2最新登录网址_漫蛙manwa2手机网页版入口
《燕云十六声》两周内达九百万玩家!位居畅销榜第五
微信网页版官方入口教程 微信网页版网页版快速登录步骤
深入理解Promise链:如何在catch后中断then的执行
Win11怎么开启高性能模式_Windows 11电源计划优化设置
12306选座怎么选到特殊座位_12306特殊座位选择注意事项
台积电1.4nm工艺A14瞄准2028:10年来性能提升80%
Win11 BitLocker密码忘了怎么办 Win11找回BitLocker恢复密钥方法【解决】
实现分段式页面滚动导航:CSS与J*aScript教程
Angular响应式表单:实现提交后表单及按钮的禁用与只读化
如何在CSS中使用浮动制作导航栏_float实现水平菜单
Composer的 archive 命令怎么用_快速打包你的PHP项目及其Composer依赖
怎样在Excel中做仪表盘_Excel仪表盘设计与关键指标展示方法
css子元素高度不一致导致布局错位怎么办_使用align-items:stretch解决高度差异
Golang如何实现Web文件静态资源服务器_Golang静态资源服务器开发与实践
taptap防沉迷怎么解除 taptap解除健康系统限制说明【2025最新】
如何使用J*aScript精确选择并批量修改特定父元素下子链接的样式
Python多版本共存与虚拟环境管理深度指南
必由学官方网站入口 必由学学生教师共用登录通道
Django表单验证失败时保留用户输入数据的最佳实践
PHP中高效并行检查多链接状态的教程
在FastAPI中利用lifespan与依赖注入高效管理Redis连接池
铁路12306的积分有效期是多久_铁路12306积分有效期说明
Win11怎么关闭触摸屏_Windows 11禁用HID符合标准触摸屏
多闪网页版在线观看免费入口_多闪官网访问入口
Yandex官网免登录入口_俄罗斯Yandex搜索引擎一键访问
CSS图片焦点样式实现教程:理解与应用tabindex属性
Django表单提交验证失败后保持字段值不刷新
现代化 SciPy 一维插值:interp1d 的替代方案与最佳实践
html怎么运行外部js文件中的函数_运html外js文件函数法【技巧】
在哪找SublimeJ远程工具_SFTP插件配置教程
Python实时数据流中的动态最值查找策略
Go语言中Map存储的结构体如何调用指针方法:深入解析与实践
三星ZFold5多任务卡顿_Samsung ZFold5流畅度提升
Django AJAX 文件上传教程:解决图片无法保存到模型的常见问题
神经网络二分类模型训练异常:高损失与完美验证准确率的排查与修正
Composer的 "check-platform-reqs" 命令有什么用_在部署前检查生产环境是否满足Composer依赖需求
解决Bootstrap卡片顶部边距导致背景图下移的问题
钉钉视频会议声音异常如何处理 钉钉会议音频修复技巧
ArrayList与LinkedList核心操作的Big-O复杂度分析
Golang如何实现微服务鉴权与权限控制_Golang微服务鉴权与权限管理实践
探索高级语言到原生C/C++的转译:挑战与内存管理策略
谷歌google账号注册详细步骤 谷歌账号注册官方教程
J*aScript Promise链中如何正确终止后续.then执行并处理错误
Lar*el 递归关系中排除指定分支的教程


2025-11-02
浏览次数:次
返回列表
"fmt"
"log"
"net/http"
"path/filepath"
)
// GlobDir 是一个自定义的 http.FileSystem 实现,用于过滤文件,只允许访问符合指定模式的文件。
type GlobDir struct {
Dir http.Dir
Pattern string
}
// Open 方法实现了 http.FileSystem 接口,用于打开文件。
func (d GlobDir) Open(name string) (http.File, error) {
baseName := filepath.Base(name)
ok, err := filepath.Match(d.Pattern, baseName)
if err != nil {
return nil, err
}
if !ok {
return nil, fmt.Errorf("%s not match GlobDir pattern.", baseName)
}
return d.Dir.Open(name)
}
func main() {
// 假设静态文件位于 /tmp/dtest 目录
fileHandler := http.FileServer(GlobDir{
Dir: http.Dir("/tmp/dtest"),
Pattern: "*.js",
})
// 将处理程序注册到服务器
http.Handle("/", fileHandler) // 注意这里需要指定路由
// 启动服务器
log.Fatal(http.ListenAndServe(":8080", nil))
}