go 编写的 cgi 程序是二进制可执行文件,非脚本,无需解释器;apache 需启用 execcgi 并正确设置文件权限(如 755),而非依赖 addhandler 绑定扩展名。
在 Apache 中运行 Go 编写的 CGI 程序,关键在于理解其本质:Go 程序编译后是静态链接的 Unix 可执行文件(ELF 格式),不是需解释器执行的脚本(如 Python/Perl)。因此,AddHandler cgi-script .go 或 .exe 不仅无效,反而可能误导 Apache 尝试用脚本方式处理二进制文件,导致浏览器直接下载而非执行。
✅ 正确配置步骤如下:
-
确保 CGI 模块已启用
运行 a2enmod cgi(Debian/Ubuntu)或确认 LoadModule cgi_module modules/mod_cgi.so 在 httpd.conf 中未被注释。 -
使用标准 cgi-bin 目录(推荐)
Apache 默认对 /cgi-bin/ 启用 ExecCGI,无需额外 AddHandler。将编译好的 Go 程序(如 hello.cgi)放入该目录:sudo cp ./hello /usr/lib/cgi-bin/hello.cgi sudo chmod 755 /usr/lib/cgi-bin/hello.cgi
⚠️ 注意:文件名后缀 .cgi 仅为约定,无实际作用;Apache 依据目录权限和 Options +ExecCGI 判断是否可执行,不依赖扩展名。
-
若必须自定义 CGI 目录(如 /var/www/html/cgi),请精简配置
移除无效的 AddHandler,仅保留权限与执行控制:Options +ExecCGI AddHandler cgi-script .cgi # 仅用于显式标识(可选),但非必需 Require all granted # 不要写 .go/.exe —— Go 二进制无需解释器? 关键点:AddHandler 在此场景中仅起“标记”作用,真正触发执行的是 Options +ExecCGI 和文件可执行权限(x 位)。
-
Go 程序需符合 CGI 规范
必须输出标准 HTTP 头(至少 Content-Type)并换行后输出正文:package main import ( "fmt" "os" ) func main() { fmt.Println("Content-Type: text/plain\n") // 注意两个换行符 fmt.Println("Hello from Go CGI!") }编译时建议静态链接,避免部署环境缺失动态库: