You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:27:09