18910140161

在Perl标记堆栈中显示HTML溢出

顺晟科技

2022-10-19 12:04:16

159

我有一个Perl脚本,它建立了一个DB连接,并以HTML格式显示输出。它试图显示的数据中嵌入了标记(<>),因此不会显示HTML。如果我打开脚本使用记事本生成的实际HTML文件,我会看到数据。然而,由于标签的原因,我无法显示它。知道如何解决这个问题吗?

#!/usr/bin/perl
use DBI;
use HTML::Escape 'escape_html';

unlink("D:\\Perl32\\scripts\\UndeliveredRAW.html");

my $host = '${Node.Caption}';
my $user = '${USER}';
my $pwd = '${PASSWORD}';
my $driver = "SQL Server";


$dbhslam = DBI->connect("dbi:ODBC:Driver=$driver;Server=$host;UID=$user;PWD=$pwd") || die "connect failed:";
$sthslam = $dbhslam->prepare("SELECT
  DBA_Reports.dbo.undelivered_raw_host_msgs.ID
  DBA_Reports.dbo.undelivered_raw_host_msgs.MESSAGE
FROM
  DBA_Reports.dbo.undelivered_raw_host_msgs");

$sthslam->execute;
$msg = "Up";
$Count = 0;
$Output = "";
$Temp = "";
$tbl = "<TABLE border=1  bordercolor=orange cellspacing=0 cellpadding=1>";
$tblhd = "<TR><TH>ID</TH><TH>MESSAGE</TH></TR>";

while (my $ref = $sthslam->fetchrow_hashref()) {
       $Count++;
    $Output .= '<TR><TD align=center rowspan=1 valign=top width=1000 height=1000>'
            . $ref->{'ID'}.'</TD>'
            .  '<TD align=center rowspan=1 valign=top width=1000 height=1000>'
            .  escape_html($ref->{'MESSAGE'}).'</TD></TR>';
}

$dbhslam->disconnect;

$Output = "$tbl$tblhd$Output</TABLE>";

my $filename1 = 'D:\\Perl32\\Scripts\\UndeliveredRAW.html';
open(my $fh1, '>', $filename1) or die "Could not open file '$filename1' $!";
print $fh1 "$Output";
close $fh1;

if ($Count > 0) {
    $msg = $Output;
}

print "\nMessage: $msg";
print "\nStatistic: $Count";

期望输出

生成的HTML内容


顺晟科技:

下面的代码片段演示了已发布代码的稍微修改版本。

有关数据库获取数据的用法,请参阅循环部分。

#!/usr/bin/perl
use DBI;
use HTML::Escape 'escape_html';

unlink("D:\\Perl32\\scripts\\UndeliveredRAW.html");

my $host = '${Node.Caption}';
my $user = '${USER}';
my $pwd = '${PASSWORD}';
my $driver = "SQL Server";


$dbhslam = DBI->connect("dbi:ODBC:Driver=$driver;Server=$host;UID=$user;PWD=$pwd") || die "connect failed:";
$sthslam = $dbhslam->prepare("SELECT
  DBA_Reports.dbo.undelivered_raw_host_msgs.ID
  DBA_Reports.dbo.undelivered_raw_host_msgs.MESSAGE
FROM
  DBA_Reports.dbo.undelivered_raw_host_msgs");

$sthslam->execute;
$msg = "Up";
$Count = 0;
$Output = "";
$Temp = "";
$tbl = "<TABLE border=1  bordercolor=orange cellspacing=0 cellpadding=1>";
$tblhd = "<TR><TH>ID</TH><TH>MESSAGE</TH></TR>";

while (my $ref = $sthslam->fetchrow_hashref()) {
       $Count++;
    $Output .= '<TR><TD align=center rowspan=1 valign=top width=1000 height=1000>'
            . $ref->{'ID'}.'</TD>'
            .  '<TD align=center rowspan=1 valign=top width=1000 height=1000>'
            .  escape_html($ref->{'MESSAGE'}).'</TD></TR>';
}

$dbhslam->disconnect;

$Output = "$tbl$tblhd$Output</TABLE>";

my $filename1 = 'D:\\Perl32\\Scripts\\UndeliveredRAW.html';
open(my $fh1, '>', $filename1) or die "Could not open file '$filename1' $!";
print $fh1 "$Output";
close $fh1;

if ($Count > 0) {
    $msg = $Output;
}

print "\nMessage: $msg";
print "\nStatistic: $Count";

注意:为了避免使用HTML样式属性污染代码,请花点时间学习CSS,生成的HTML不包括必需的部分doctypehtmlheadtitlebody

参考:

HTML有一个很好理解的机制来包含通常被解释为特殊字符的字符。例如,如果要在HTML中包含一个元素,则通常将其视为在文档中开始一个新的HTML元素。

解决方案是用表示这些字符的HTML实体替换这些有问题的字符。例如,应替换为。请注意,这意味着如果要将与号()包含在HTML中,则需要将其添加到应该替换的字符集合中。

Perl在web上使用已有很长的历史,因此有许多工具可以进行这种替换也就不足为奇了。html::escape可能是最著名的。它提供了一个函数(),该函数接受一个文本字符串,并返回相同的字符串,所有有问题的字符都被适当的实体替换。

#!/usr/bin/perl
use DBI;
use HTML::Escape 'escape_html';

unlink("D:\\Perl32\\scripts\\UndeliveredRAW.html");

my $host = '${Node.Caption}';
my $user = '${USER}';
my $pwd = '${PASSWORD}';
my $driver = "SQL Server";


$dbhslam = DBI->connect("dbi:ODBC:Driver=$driver;Server=$host;UID=$user;PWD=$pwd") || die "connect failed:";
$sthslam = $dbhslam->prepare("SELECT
  DBA_Reports.dbo.undelivered_raw_host_msgs.ID
  DBA_Reports.dbo.undelivered_raw_host_msgs.MESSAGE
FROM
  DBA_Reports.dbo.undelivered_raw_host_msgs");

$sthslam->execute;
$msg = "Up";
$Count = 0;
$Output = "";
$Temp = "";
$tbl = "<TABLE border=1  bordercolor=orange cellspacing=0 cellpadding=1>";
$tblhd = "<TR><TH>ID</TH><TH>MESSAGE</TH></TR>";

while (my $ref = $sthslam->fetchrow_hashref()) {
       $Count++;
    $Output .= '<TR><TD align=center rowspan=1 valign=top width=1000 height=1000>'
            . $ref->{'ID'}.'</TD>'
            .  '<TD align=center rowspan=1 valign=top width=1000 height=1000>'
            .  escape_html($ref->{'MESSAGE'}).'</TD></TR>';
}

$dbhslam->disconnect;

$Output = "$tbl$tblhd$Output</TABLE>";

my $filename1 = 'D:\\Perl32\\Scripts\\UndeliveredRAW.html';
open(my $fh1, '>', $filename1) or die "Could not open file '$filename1' $!";
print $fh1 "$Output";
close $fh1;

if ($Count > 0) {
    $msg = $Output;
}

print "\nMessage: $msg";
print "\nStatistic: $Count";

运行此代码后,现在包含“$lt;一些文本$gt;$amp;$lt;一些其他文本$gt;”。如果将该文本发送到浏览器,将显示正确的输出。

所以最简单的解决方案是在程序顶部加载HTML::Escape,然后在向输出添加可能有问题的字符串时调用。这意味着您的循环如下所示:

#!/usr/bin/perl
use DBI;
use HTML::Escape 'escape_html';

unlink("D:\\Perl32\\scripts\\UndeliveredRAW.html");

my $host = '${Node.Caption}';
my $user = '${USER}';
my $pwd = '${PASSWORD}';
my $driver = "SQL Server";


$dbhslam = DBI->connect("dbi:ODBC:Driver=$driver;Server=$host;UID=$user;PWD=$pwd") || die "connect failed:";
$sthslam = $dbhslam->prepare("SELECT
  DBA_Reports.dbo.undelivered_raw_host_msgs.ID
  DBA_Reports.dbo.undelivered_raw_host_msgs.MESSAGE
FROM
  DBA_Reports.dbo.undelivered_raw_host_msgs");

$sthslam->execute;
$msg = "Up";
$Count = 0;
$Output = "";
$Temp = "";
$tbl = "<TABLE border=1  bordercolor=orange cellspacing=0 cellpadding=1>";
$tblhd = "<TR><TH>ID</TH><TH>MESSAGE</TH></TR>";

while (my $ref = $sthslam->fetchrow_hashref()) {
       $Count++;
    $Output .= '<TR><TD align=center rowspan=1 valign=top width=1000 height=1000>'
            . $ref->{'ID'}.'</TD>'
            .  '<TD align=center rowspan=1 valign=top width=1000 height=1000>'
            .  escape_html($ref->{'MESSAGE'}).'</TD></TR>';
}

$dbhslam->disconnect;

$Output = "$tbl$tblhd$Output</TABLE>";

my $filename1 = 'D:\\Perl32\\Scripts\\UndeliveredRAW.html';
open(my $fh1, '>', $filename1) or die "Could not open file '$filename1' $!";
print $fh1 "$Output";
close $fh1;

if ($Count > 0) {
    $msg = $Output;
}

print "\nMessage: $msg";
print "\nStatistic: $Count";

注意,我已经删除了变量(它似乎没有做任何有用的事情),并切换到用于构建输出字符串。是“赋值串联”运算符-它将右边的新字符串添加到左边变量中当前存在的内容的末尾。

您似乎是在工作中学习Perl(这很棒),但真正令人遗憾的是,您是在一个似乎使用过时了大约20年的技术的环境中学习Perl的。您的问题是一个很好的例子,说明为什么试图在Perl代码中构建原始HTML字符串是一个坏主意。使用某种模板引擎是一个更好的主意(Perl世界中的defacto标准似乎是the Template toolkit).

我还建议将级联样式表作为一种更现代的HTML输出样式化方法。

  • TAG:
相关文章
我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航