繁体   English   中英

使用Perl提供图片会显示错误的内容长度(在Chrome中为net :: ERR_CONTENT_LENGTH_MISMATCH)

[英]Serving Image with Perl prints wrong Content-Length (Gives net::ERR_CONTENT_LENGTH_MISMATCH in Chrome)

Activeperl 5.16 + Windows环境。

Windows机器:

我的perl5(修订版5,版本16,版本3)的摘要:

Linux机器:

我的perl5(修订版5,版本14,版本2)的摘要:

完全不会在具有相同代码的Linux上发生。

这是我的代码,获取天气gif图像,并做了一些魔术处理(从高速缓存的目录中提供故障转移支持,以防Internet中断或远程服务器在获取过程中进行雷达更新,然后脱机)

sub get_map
{
    my $whichImage = $_[0];

    my $ua = LWP::UserAgent->new;
    my $cache_file      = $GLOB{'cache_mapA'};          # tempdata file path
    my $cache_file_age  = 100000;                       # this is used to determine if we have to get fresh data from the ems site will hold the tempdata file age in seconds 
    my $data            = '';                           # initializing empty data variable to enable later check for empty variable
    my $cache_time      = $GLOB{'cache_timeMap'};       # Max age of the temdata file in seconds
    my $useCached       = 0;
    my $url             = $GLOB{'mapAurl'};

    if( $whichImage eq "B" )
    {
        $cache_file     = $GLOB{'cache_mapB'};
        $url            = $GLOB{'mapBurl'};
    }

    if ( -s $cache_file )   # test existence of the tempdata file - if it has a size it exists
    {
        my $mtime           = ( stat $cache_file )[9];  # get the Unix time of the last change (in seconds)
        my $current_time    = time;                     # get the current Unix time (in  seconds)
        $cache_file_age     = $current_time - $mtime;       # get the age of the tempdata fileim seconds!       
    }

    if( $cache_file_age > $cache_time ) # check if we have to query the ems server 
    {
        my $response = $ua->get($url);

        if ($response->is_success) # checking if we were able to get the website
        {
            $data = $response->decoded_content( charset => 'none' );
            open my $filehandle , '>' , $cache_file or die 'Horribly';  
            binmode $filehandle;
            print $filehandle $data;
            close $filehandle;
        }
    }

    my $file = $cache_file;
    my $length = -s $file;

    print "Content-type: image/gif\n";
    print "Content-length: $length \n\n";

    binmode STDOUT;

    open (FH,'<', $file) || die "Could not open $file: $!";
    my $buffer = "";

    while (read(FH, $buffer, 10240)) 
    {
        print $buffer;
    }
    close(FH);
}

cache_mapA指向tmp / map.A.gif和缓存

转到http://mywebserver.com/whatever.cgi?type=mapA会给出损坏的gif文件,该文件在Google Chrome浏览器的调试器中显示net :: ERR_CONTENT_LENGTH_MISMATCH。

转到http://mywebserver.com/tmp/map.A.gif在浏览器中可以正常工作。

在我的测试箱上尝试过的交换服务器软件Apache和LightTPD都显示了此行为。

我没有想法,因为这在非基于Windows的计算机上可以很好地工作。

这部分可能有问题,但对我来说看起来不错:

print "Content-type: image/gif\n";
print "Content-length: $length \n\n";

binmode STDOUT;

open (FH,'<', $file) || die "Could not open $file: $!";
my $buffer = "";

while (read(FH, $buffer, 10240)) 
{
    print $buffer;
}
close(FH);

救命!

您执行了binmode STDOUT ,但未执行binmode FH Windows Perl将打开默认情况下启用:crlf文件; Unix Perl没有。

更现代的技术将是open (FH,'<:raw', $file)而不是使用对binmode的单独调用。

如果该图像在其他浏览器中显示,则该特定图像的损坏可能很小,无法阻止解码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM