2012-10-07 45 views
1

我正在使用XML :: Code從通過CGI模塊接收的GET參數創建一些XML數據。網絡服務器是Apache加上字符集設置爲UTF-8和提交表單是在頁面上用Perl cgi和XML ::代碼雙重編碼問題

<!DOCTYPE html> 
<html lang="en-GB"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 

報頭。該CGI看起來像這樣:

use CGI; 
use Encode; 
use XML::Code; 
binmode(STDOUT, ":utf8"); 
binmode(STDIN, ":utf8"); 

my $cgi = CGI->new(); 
print $cgi->header(-type => "text/xml", -charset => "utf-8"); 
my $object = $cgi->param("object"); 
$object = decode("utf-8", utf8::upgrade($object)); 

my $content = XML::Code->new("formdata"); 
$content->version ("1.0"); 
$content->encoding ("UTF-8"); 

my $sub_content = XML::Code->new("object"); 
$sub_content->set_text($object); 
$content->add_child($sub_content); 

$sub_content = XML::Code->new("isutf"); 
$sub_content->set_text(utf8::is_utf8($object)); 
$content->add_child($sub_content); 

print $content->code(); 

當調用與http://mydomain.com/cgi-bin/formdata.pl?object cgi的= O的輸出(從螢火蟲複製)是

<?xml version="1.0" encoding="UTF-8"?> 
<formdata> 
    <object>ö</object> 
    <isutf>1</isutf> 
</formdata> 

卸下binmode(STDOUT, 「:UTF8」)從CGI給我什麼,我找

<?xml version="1.0" encoding="UTF-8"?> 
<formdata> 
    <object>ö</object> 
    <isutf>1</isutf> 
</formdata> 

現在我知道如何解決這個問題,但我認爲一切都設置爲UTF-8的時候我會很安全。如果我不是這將意味着更多的測試。這是在perl庫或我的想法中的錯誤?

最佳, 馬庫斯

回答

0

我認爲以下行:

$object = decode("utf-8", utf8::upgrade($object)); 

可能沒有幫助。在對字符串進行就地操作之後,utf8 :: upgrade returns a number of octets。如果您將其保留爲:

$object = decode("utf-8", $object); 

那麼您可能會有更多可理解的行爲。

我想我已經想通了,一點多用這種簡短的腳本的幫助:

#! /usr/bin/perl -w 
use Encode; 
binmode(STDOUT, ":utf8"); 
my $string = "\x{C3}\x{B6}"; 
print "$string\n"; 
my $decoded = decode("UTF8", $string); 
print "$decoded\n"; 

的輸出是:

ö 
ö 

因此,這裏是我相信發生了什麼。上面的$ string聲明是您從調用cgi-> param返回的內容,也就是說它是兩個字節,代表UTF-8中的ö。當腳本第一次打印它時,Perl沒有指示這是UTF-8,但知道它必須在打印之前先將其轉換(由於binmode)。

Perl的默認行爲是假設將被解釋爲字符串的八位字節流編碼爲Latin-1。因此,它需要第一個字節C3查找它在Latin-1中的內容,然後打印出等同於STDOUT的UTF-8。 B6一樣。您可以仔細檢查Wikipedia上的字節。

但是,解碼調用會將字節解釋爲UTF-8並創建一個由字符ö組成的新字符串。不要認爲字符串具有編碼;進出的字節需要編碼,但在你的程序中,一旦它們被正確解釋,那麼它們就是字符串。

現在,Perl已經解釋了這些字節並轉換爲使用任何內部編碼進行編碼的字符串,當您下一次打印出來時,它知道要將字符轉換爲UTF-8,並且您得到正確的輸出。

希望能夠幫助您調試CGI。

+0

感謝您的快速響應! – Marcus