Perl CGI脚本在网页端显示空白的问题求助
我编写的Perl CGI脚本在终端执行正常,但通过Unix系统的Apache2网页服务器访问时显示空白。将网页内容移至数据库连接代码上方即可正常显示,数据库连接后的内容无法在浏览器中呈现。脚本已配置执行权限,具体代码如下:
#!/usr/bin/perl use strict; use warnings; use DBI; use CGI; print "Content-type: text/html\n\n"; # Simple HTML code follows my $driver= "Oracle"; my $dsn = "DBI:$driver:sid=xxxxx;host=xxxxx;port=1521"; my $dbh = DBI->connect($dsn,'xxxx','xxxx'); #print $dbh; my $sth = $dbh->prepare("SELECT * FROM TABLE WHERE ROWNUM <= 10"); $sth->execute; print "<html> <head>\n"; print "<title>Hello, world!</title>"; print "</head>\n"; print "<body>\n"; print "<h1>Hello, world!</h1>\n"; print "<p>The Details are as follows:</p>\n"; print "<table cols=5 border=1>\n"; print "<tr>\n"; print "<th>ACTION</th>\n"; print "<th>ALARM_TEXT</th>\n"; print "<th>ALARM_SEV</th>\n"; print "<th>EMS_NAME</th>\n"; print "</tr>"; while( my $ref = $sth->fetchrow_hashref() ) { print "<tr>\n"; print "<td>", $ref->{'ACTION'}, "</td>\n"; print "<td>", $ref->{'ALARM_TEXT'}, "</td>\n"; print "<td>", $ref->{'ALARM_SEV'}, "</td>\n"; print "<td>", $ref->{'EMS_NAME'}, "</td>\n"; print "<tr>\n"; } print "</table>\n"; print "<h1>Hello, world!</h1>\n"; print "</body> </html>\n";
这种情况大概率是数据库连接或查询执行失败导致脚本直接终止,但因为你没加错误处理逻辑,脚本崩溃后没有输出任何内容,浏览器就显示空白。
终端执行正常是因为用的是你个人用户的权限,而Apache运行CGI的用户(通常是www-data或apache)可能没有访问Oracle数据库的权限、缺少必要的环境变量(比如ORACLE_HOME),甚至连接参数存在问题。
给你几个具体的解决步骤:
1. 调整内容输出顺序,避免完全空白
把基础HTML结构的输出移到数据库连接之前,这样即使连接失败,至少能看到页面框架和错误提示,而不是一片空白。
2. 给数据库操作添加错误处理
Perl的DBI模块在操作失败时默认会触发die终止脚本,所以必须在connect、prepare、execute这些关键步骤后加上错误检查,把错误信息输出到页面上,同时闭合HTML标签保证页面结构完整。
3. 查看Apache错误日志
直接去看Apache的错误日志(通常路径是/var/log/apache2/error.log),里面会记录CGI执行时的具体错误,比如权限不足、Oracle库文件找不到等,这是排查问题的核心依据。
下面是修改后的完整代码,重点标注了错误处理和内容调整的部分:
#!/usr/bin/perl use strict; use warnings; use DBI; use CGI; # 先输出Content-Type头,这是CGI的必要步骤 print "Content-type: text/html\n\n"; # 先输出基础HTML结构,确保即使出错也有内容显示 print "<html> <head>\n"; print "<title>Hello, world!</title>"; print "</head>\n"; print "<body>\n"; print "<h1>Hello, world!</h1>\n"; print "<p>The Details are as follows:</p>\n"; my $driver= "Oracle"; my $dsn = "DBI:$driver:sid=xxxxx;host=xxxxx;port=1521"; # 数据库连接添加错误处理,输出错误信息并闭合HTML标签 my $dbh = DBI->connect($dsn,'xxxx','xxxx') or die "<p>数据库连接失败: " . DBI->errstr . "</p></body></html>"; # 预处理SQL语句添加错误处理 my $sth = $dbh->prepare("SELECT * FROM TABLE WHERE ROWNUM <= 10") or die "<p>预处理SQL失败: " . $dbh->errstr . "</p></body></html>"; # 执行查询添加错误处理 $sth->execute() or die "<p>执行查询失败: " . $sth->errstr . "</p></body></html>"; # 输出表格内容 print "<table cols=5 border=1>\n"; print "<tr>\n"; print "<th>ACTION</th>\n"; print "<th>ALARM_TEXT</th>\n"; print "<th>ALARM_SEV</th>\n"; print "<th>EMS_NAME</th>\n"; print "</tr>"; while( my $ref = $sth->fetchrow_hashref() ) { print "<tr>\n"; print "<td>", $ref->{'ACTION'}, "</td>\n"; print "<td>", $ref->{'ALARM_TEXT'}, "</td>\n"; print "<td>", $ref->{'ALARM_SEV'}, "</td>\n"; print "<td>", $ref->{'EMS_NAME'}, "</td>\n"; print "</tr>\n"; # 原代码这里写错了,是</tr>不是<tr>,会导致HTML结构错误 } print "</table>\n"; print "<h1>Hello, world!</h1>\n"; print "</body> </html>\n"; # 关闭语句句柄和数据库连接,养成良好的资源释放习惯 $sth->finish(); $dbh->disconnect();
另外注意你原代码里的一个小错误:while循环最后一行是print "<tr>\n";,应该是print "</tr>\n";,这个错误会破坏HTML结构,也可能影响页面正常显示。
内容的提问来源于stack exchange,提问作者Sujeet Padhi

