我有一个 Javascript/Ajax 文件 uploader ( https://github.com/Valums-File-Uploader/file-uploader ),它在 latin-1 编码的网页上运行良好。现在我尝试在 UTF-8 环境中使用它,但失败了。
这是我的代码(我只需要变量中的图像,保存在其他地方完成):
sub parseMultiPart{
use CGI;
use IO::Handle;
use Encode;
$CGITempFile::TMPDIRECTORY = $ENV{ADFRAME_TMP_FILES};
$CGI::POST_MAX=1024 * 1024 * 5;
#$CGI::PARAM_UTF8=1;
my $cgi = new CGI;
foreach $key ($cgi ->param) {
my $upload = $cgi->upload($key);
if(defined $upload) {
# THIS DOES NOTHING SINCE UPLOAD IS NOT DEFINED
my $file=$cgi->param($key);
binmode $upload;
my $data;
while (read($upload_file, $upload, 1024)) {
$main::in{$key} .= $data;
}
$main::inct{$key} = $cgi->uploadInfo($file)->{'Content-Type'};
}
else {
my @val = $cgi->param($key);
# THIS DOES THE WORK
if (scalar @val == 1) {
$main::in{$key} = $val[0];
}
# /
else {
$main::in{$key} = \@val; # save value as an array ref
}
}
}
}
1;
然后下一步:
if (open (HI, ">$storePath/$filename")) {
binmode HI;
print HI $data;
close(HI);
}
这里有几个问题:
-
CGI->upload()
无法识别这是上传。我现在才注意到,因为它从未造成任何问题。 - 使用
multipart/formdata
导致服务器中止并且不发送任何内容。 - 像这样使用它我得到
Wide character in print
消息。 - 如果我
encode $val[0]
我不会收到该消息,生成的文件仍然损坏。 - 如果我
binmode $val[0]
我得到wide characters in print
谁能帮忙吗?
谢谢,
托马斯
编辑:这是“跟随 TCP 流”:
POST /cgi-bin/adframe/upload/image_upload.html?ITEM_ID=1&CATEGORY=1_1&qqfile=button_logout.gif HTTP/1.1
Host: productspecial
Connection: keep-alive
Content-Length: 583
Origin: http://productspecial
X-Mime-Type: image/gif
X-Requested-With: XMLHttpRequest
X-File-Name: button_logout.gif
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11
Content-Type: application/octet-stream
Accept: */*
Referer: http://productspecial/cgi-bin/adframe/online_produktdatenbank/1_komplettbikes/1_1_fullsuspension/1_1_fullsuspension.html?ITEM_ID=1&id=134149338812700131663
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
GIF89aD......................................................................................................!.......,....D........ud...Y.*y....qJ....8.....6..[..rh,....ez..lI.q.D....&........n.....B.....>..L..u.............$...........}..............................}..}........................}....}...}.........}...................}...4h.............A...H.(P.....q..qB....<.8.CI..I..4y..H..^Z..kB...=t.S...>......(J.D{*U*<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8fdda1cff5a1a1dd" rel="noreferrer noopener nofollow">[email protected]</a>...@0.
.>.. k@
<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4f6161610f616161616128616122" rel="noreferrer noopener nofollow">[email protected]</a>%....p.V.K.n].t..........I.,A0a....^l......
n...a..+..........V....p.T.FMa5j..N..M.....s......
.y.........+_..A....K.N.....;HTTP/1.1 200 OK
Date: Thu, 05 Jul 2012 13:32:09 GMT
Server: Apache/2.2.20 (Ubuntu)
Cache-Control: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 104
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
.............MNN-..*)*M.I..I.R.O.-...MLO-./J,.wqus....+.KW.)-..R..utw.7.C..4SKsSK...4u...*..5...~.
.Y...
最佳答案
您的 Content-Type 不适用于 CGI->上传,来自 CGI 文档
If POSTed data is not of type application/x-www-form-urlencoded or multipart/form-data, then the POSTed data will not be processed, but instead be returned as-is in a parameter named POSTDATA. To retrieve it, use code like this:my $data = $query->param('POSTDATA');
更新:这是针对 CGI.pm-3.59 的补丁,以避免 PUTDATA/POSTDATA 损坏
它还提供了 PUTDATA/POSTDATA 便捷方法来代替 param
diff -ruN CGI.pm-3.59-orig/lib/CGI.pm CGI.pm-3.59/lib/CGI.pm
--- CGI.pm-3.59-orig/lib/CGI.pm 2011-12-30 05:31:41.000000000 -0800
+++ CGI.pm-3.59/lib/CGI.pm 2012-07-25 05:08:19.656250000 -0700
@@ -20,7 +20,7 @@
# The revision is no longer being updated since moving to git.
$CGI::revision = '$Id: CGI.pm,v 1.266 2009/07/30 16:32:34 lstein Exp $';
-$CGI::VERSION='3.59';
+$CGI::VERSION='3.5901';
# HARD-CODED LOCATION FOR FILE UPLOAD TEMPORARY FILES.
# UNCOMMENT THIS ONLY IF YOU KNOW WHAT YOU'RE DOING.
@@ -457,8 +457,12 @@
my @result = @{$self->{param}{$name}};
if ($PARAM_UTF8) {
- eval "require Encode; 1;" unless Encode->can('decode'); # bring in these functions
- @result = map {ref $_ ? $_ : $self->_decode_utf8($_) } @result;
+ if( $name eq 'PUTDATA' or $name eq 'POSTDATA' ){
+ warn "skip decoding utf8 for special param $name\n" if DEBUG;
+ } else {
+ eval "require Encode; 1;" unless Encode->can('decode'); # bring in these functions
+ @result = map {ref $_ ? $_ : $self->_decode_utf8($_) } @result;
+ }
}
return wantarray ? @result : $result[0];
@@ -692,7 +696,7 @@
&& defined($ENV{'CONTENT_TYPE'})
&& $ENV{'CONTENT_TYPE'} !~ m|^application/x-www-form-urlencoded|
&& $ENV{'CONTENT_TYPE'} !~ m|^multipart/form-data| ) {
- my($param) = $meth . 'DATA' ;
+ my($param) = $meth . 'DATA' ; # POSTDATA/PUTDATA
$self->add_parameter($param) ;
push (@{$self->{param}{$param}},$query_string);
undef $query_string ;
@@ -985,6 +989,14 @@
%SUBS = (
+'PUTDATA'=> <<'END_OF_FUNC',
+sub PUTDATA { local $CGI::PARAM_UTF8=0; shift()->param('PUTDATA', @_) }
+END_OF_FUNC
+
+'POSTDATA'=> <<'END_OF_FUNC',
+sub POSTDATA { local $CGI::PARAM_UTF8=0; shift()->param('POSTDATA', @_) }
+END_OF_FUNC
+
'URL_ENCODED'=> <<'END_OF_FUNC',
sub URL_ENCODED { 'application/x-www-form-urlencoded'; }
END_OF_FUNC
关于ajax - 使用 Perl 从 UTF-8 网页上传带有 application/octet-stream 的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11343663/