使用Mojo :: DOM

时间:2017-12-06 08:28:52

标签: perl unicode html-entities mojolicious

我使用Mojo :: DOM Perl模块替换<IMG>标记,但&nbsp;实体被Mojo :: DOM替换为\ xa0,但当我将其打印到页面时NBSP字符变为\ x {fffd}并显示为问号。我已经尝试用&amp; nbsp;替换\ n \ n&nbsp;但这样做会破坏另一个unicode角色。这是我的代码:

#!/usr/bin/perl

use utf8;
use strict;
use warnings;
use CGI;

my $cgi = new CGI;

print $cgi->header(-charset => 'utf-8');

my %params = $cgi->Vars;

print q[<html><head><title>UTF-8 Test</title></head><body><form method="POST"><textarea name="msg" cols="50" rows="20">].$params{msg}.q[</textarea><br/><br/><input type="submit"></form>];

if($ENV{REQUEST_METHOD} eq 'POST') {
    require Mojo::DOM;


    my $dom = Mojo::DOM->new($params{msg});

    for my $e ($dom->find('img')->each) {
          my $x = $e->attr('data-char');

          if(defined($x) && $x) {
             $e->replace($x);
          }
          else {
              $e->delete;
          }
    }

    $params{msg} = $dom->to_string();
    print '<hr/><div>'.$params{msg}.'</div>';
}

print q[</body></html>];

POST的msg param的内容:

  

אֱלֹהִים,+אֵת+הַשָּׁמַיִם,+וְאֵת+הָאָרֶץ。 1在起始点   &amp; nbsp;&lt; img src =“p.jpg”data-char =“”&gt; Easy Bengali打字:বাংলাটাইপ   করুনМинюстРФопубликовалсписокСМИ-иноагентов日语键盘 -   日本语のキーボード先秦两汉(先秦两汉)

以下是输出的屏幕截图:

enter image description here

1 个答案:

答案 0 :(得分:2)

Mojo :: DOM期望使用字符,而不是UTF-8编码的字节,因此很有可能它将&nbsp;解码为一个字符,然后在输出之前需要将其编码为UTF-8。旧的CGI模块无法像现代框架那样对输入参数进行解码或对输出进行编码。因此,您需要自己处理:在将UTF-8传递给Mojo :: DOM之前,先从UTF-8解码$params{msg},然后再将其编码回UTF-8,然后将其放入输出中(您声明了毕竟是UTF-8)。

if($ENV{REQUEST_METHOD} eq 'POST') {
    require Mojo::DOM;
    require Mojo::Util;


    my $dom = Mojo::DOM->new(Mojo::Util::decode('UTF-8', $params{msg}));

    for my $e ($dom->find('img')->each) {
          my $x = $e->attr('data-char');

          if(defined($x) && $x) {
             $e->replace($x);
          }
          else {
              $e->delete;
          }
    }

    $params{msg} = Mojo::Util::encode('UTF-8', $dom->to_string());
    print '<hr/><div>'.$params{msg}.'</div>';
}