如何让Mojolicious正确处理UTF-8编码?
解决Mojolicious写入文件的宽字符错误与浏览器乱码问题
嘿,这个问题我太熟了!咱们一步步来拆解和解决它~
问题根源
你碰到的「Wide character in syswrite」错误,本质是Perl内部的Unicode宽字符和文件字节流写入的编码不匹配导致的。Mojo::DOM提取出来的文本是Perl内部存储的Unicode字符串(也就是宽字符),而Mojo::File->spurt默认是按原始字节写入文件,当字符串里包含多字节的Unicode字符时,Perl就会抛出这个错误;至于浏览器显示乱码,是因为你返回给浏览器的内容没有明确指定UTF-8编码,浏览器用了错误的编码解析。
修复后的完整代码
直接用Encode模块的encode_utf8把Unicode字符串转成UTF-8字节流就搞定了,同时给浏览器响应也明确编码:
use Mojolicious::Lite; use Mojo::UserAgent; use Mojo::File; use Encode qw/encode_utf8/; # 引入编码处理函数 get '/' => sub { my $c = shift; my $ua = Mojo::UserAgent->new; my $res = $ua->get('https://...')->result; # 替换成你的目标URL # 提取文本并编码为UTF-8后写入文件 my $target_text = $res->dom->at('.some-selector')->text; Mojo::File->new('resp')->spurt(encode_utf8($target_text)); # 给浏览器返回UTF-8编码的内容,避免乱码 $c->render(text => encode_utf8($res->body)); }; app->start;
额外小技巧
其实Mojo自身也带了编码方法,你也可以不用Encode模块,直接用Mojo字符串的encode方法:
# 替换写入文件的那行 Mojo::File->new('resp')->spurt($target_text->encode('UTF-8'));
不过Encode模块是Perl标准库的一部分,兼容性更广,两种方式都能用,看你个人习惯~
内容的提问来源于stack exchange,提问作者x-yuri
相关产品推荐
相关产品推荐

