如何使用LWP :: UserAgent强制对表单数据进行ISO-8859-1编码?

问题描述

| 似乎LWP :: UserAgent始终将表单数据编码为UTF-8,即使将其显式编码为ISO-8859-1也是如此,如下所示:
use Encode;
use LWP::UserAgent;
use utf8;

my $ua = LWP::UserAgent->new;
$ua->post(\'http://localhost:8080/\',{
    text => encode(\"iso-8859-1\",\'è\'),});
请求内容为“ 1”。如何将
è
编码为
%E8
?     

解决方法

        呵呵。 :-)这与最近十几个Perl版本中对Unicode的逐渐增长的支持以及
URI
模块使用的正则表达式功能
\\C
(更确切地说,
URI::Escape
)有关。从2010年开始在perl-unicode上阅读此线程(不要在正则表达式中使用\\ C转义-为什么不这样做?)以了解背景知识。 为什么选择“ 5”模块?因为它被用来做
HTTP::Request::Common
的形式和URL编码。 同时,这是我写的一个脚本,用以提醒自己这个问题的技巧,尤其是
URI
模块是一个经常使用的模块:
use 5.010;
use utf8;
# Perl and URI.pm might behave differently when you encode your script in
# Latin1 and drop the utf8 pragma.
use Encode;
use URI;
use Test::More;
use constant C3A8 => \'text=%C3%A8\';
use constant   E8 => \'text=%E8\';
diag \"Perl $^V\";
diag \"URI.pm $URI::VERSION\";
my $chars = \'è\';
my $octets = encode \'iso-8859-1\',$chars;
my $uri = URI->new(\'http:\');

$uri->query_form( text => $chars );
is $uri->query,C3A8,C3A8;

my @exp;
given ( \"$^V $URI::VERSION\" ) {
        when ( \'v5.12.3 1.56\' ) { @exp = (   E8,C3A8 ) }
        when ( \'v5.10.1 1.54\' ) { @exp = ( C3A8,C3A8 ) }
        when ( \'v5.10.1 1.58\' ) { @exp = ( C3A8,C3A8 ) }
        default                 { die \'not tested :-)\' }
}

$uri->query_form( text => $octets );
is $uri->query,$exp[0],$exp[0];

utf8::upgrade $octets;
$uri->query_form( text => $octets );
is $uri->query,$exp[1],$exp[1];

done_testing;
所以我得到的(在Windows和Cygwin上)是:
C:\\Windows\\system32 :: perl \\Opt\\Cygwin\\tmp\\uri.pl
# Perl v5.12.3
# URI.pm 1.56
ok 1 - text=%C3%A8
ok 2 - text=%E8
ok 3 - text=%C3%A8
1..3
和:
MiLu@Dago: ~/comp > perl /tmp/uri.pl
# Perl v5.10.1
# URI.pm 1.54
ok 1 - text=%C3%A8
ok 2 - text=%C3%A8
ok 3 - text=%C3%A8
1..3
更新 您可以手工制作请求正文:
use utf8;
use Encode;
use LWP::UserAgent;
my $chars = \'ölè\';
my $octets = encode( \'iso-8859-1\',$chars );
my $body = \'text=\' .
        join \'\',map { $o = ord $_; $o < 128 ? $_ : sprintf \'%%%X\',$o }
        split //,$octets;
my $uri = \'http://localhost:8080/\';
my $req = HTTP::Request->new( POST => $uri,[],$body );
print $req->as_string;
my $ua = LWP::UserAgent->new;
my $rsp = $ua->request( $req );
print $rsp->as_string;
    ,        
use strict;
use warnings;
use utf8;  # Script is encoded using UTF-8.

use Encode                qw( encode );
use HTTP::Request::Common qw( POST );  # This is what ->post uses

my $req = POST(\'http://localhost:8080/\',{
    text => encode(\"iso-8859-1\",\'è\'),});

print($req->as_string());
POST http://localhost:8080/
Content-Length: 8
Content-Type: application/x-www-form-urlencoded

text=%E8
您使用的是传递«è»而不是其UTF-8编码吗?如果使用其UTF-8编码,则得到的结果与您相同。
...
my $req = POST(\'http://localhost:8080/\',encode(\"UTF-8\",\'è\')),});
...
POST http://localhost:8080/
Content-Length: 11
Content-Type: application/x-www-form-urlencoded

text=%C3%A8
    ,        对自己的简短回答:只需将变量名(即\“ text \”)放在引号中,而不是将其写为裸字。
$ua->post(\'http://localhost:8080/\',{
    \'text\' => encode(\"iso-8859-1\",});
比率:这种怪异的行为是由以下因素共同导致的: Perl错误#68812导致UTF-8内部标志被设置为所有裸字。这已在最新的Perl版本(> = 5.12)中修复; URI.pm在转换字符之前将键连接到值(即\“ text =è\”),因此即使键设置了内部标志,即使将值作为八进制传递,该值也始终提升为UTF-8。 我不认为@Lumi使用
\\C
指出的有关URI.pm的错误对这个特定问题没有影响。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...