分享
 
 
 

perl常问问题集--第七篇

王朝perl·作者佚名  2008-05-18
窄屏简体版  字體: |||超大  

我的 CGI script可在指令列下执行但无法从浏览器执行。您能不能帮我修修看?

如何去除文章中的 HTML标签?

如何萃取 URLs?

如何从 user端上传资料?如何在另一台机器上开一个档案?

如何在 HTML中做 pop-up menu(跳出式选单)?

如何抓 HTML档案?

如何解开或产生 Web上那些冠 %的码?

如何【将 requests】转向到另一页去?

如何替网页加上密码?

要怎麽用 Perl来编辑 .htpasswd和 .htgroup这两个档案?

如何防范使用者藉由填我的 CGI表格来做坏事?

如何解读、萃取 email标头资料?

如何解译 CGI表格?

如何验证 email位址?

如何解 MIME/BASE64字串?

如何根据使用者帐户名称自动合成 email位址?

我的程式如何送/读 email?

如何找出我的主机名/网域名/IP位址?

如何抓新闻讨论群的文章或群组名录?

如何抓/丢 FTP档案?

如何用 Perl做 RPC?

作者及版权事宜

--------------------------------------------------------------------------------

篇名

perlfaq9 -网路连线(原文版 Revision: 1.16, Date: 1997/04/23 18:12:06. 中文版 $Revision: 1.13 $, $Date: 1997/07/12 20:44:25 $)

--------------------------------------------------------------------------------

概述

本篇涵盖网路连线、 Internet ,还有几个关於 WWW 的问题。

--------------------------------------------------------------------------------

我的 CGI script可在指令列下执行但无法从浏览器执行。您能不能帮我修修看?

当然,但您恐怕付不起雇我们的签约金 :-)

说真的,如果您能够先证明您已读过下列这几个 FAQs ,但遇到的问题并不单纯、非叁言两语即可回答的话,那麽您 post到 comp.infosystems.www.authoring.cgi上(如果是有关 HTTP 、 HTML ,或 CGI通信协定)的问题可能也会得到口气和缓而有用的答覆。表面上看似 Perl,但骨子里是 CGI之类的问题,如果 post到 comp.lang.perl.misc人家可能就不会这麽乐意地接受了。

几个实用的 FAQs 分别是:

http://www.perl.com/perl/faq/idiots-guide.html

http://www3.pair.com/webthing/docs/cgi/faqs/cgifaq.shtml

http://www.perl.com/perl/faq/perl-cgi-faq.html

http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq.html

http://www.boutell.com/faq/

【译者】上面第叁份文件,Perl-CGI-FAQ的中译版可在 http://2Ti.com/cgi-bin/2T/perl/perl-cgi-faq-chi/ 处取得。最後一份(WWW FAQ)的中译版可自 http://www.acer.net/document/cwwwfaq/ 取得。

--------------------------------------------------------------------------------

如何去除文章中的 HTML标签?

最正确(尽管不是最快)的方法是使用 HTML::Parse模组(可由 CPAN取得,是所有写 Web程式者必备的 libwww-perl 套件的一部分)。

许多人尝试用简陋的正规表示式来解决这个问题,譬如说像 s///g,但这个式子在很多情况下会失败,因为要处理的字串可能会跨越断行字元,也可能含有被 quote【跳脱】的箭头号,或有 HTML comment出现;再加上一些疏忽,譬如,人们常忘了转换如 '"]*|(['"]).*?\1)*>//gs

如果您想要更完整的解法,请看叁部曲的 striphtml 程式, http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/striphtml.gz 。

--------------------------------------------------------------------------------

如何萃取 URLs?

一个快速但不完美的做法是

#!/usr/bin/perl -n00

# qxurl - tchrist@perl.com

print "$2\n" while m{

}gsix;

这个版本并不替相对式写法的 URLs 作调整,也不懂代换 bases【】,或如何处理 HTML comments、同时处理同一个标签里的 HREF和 NAME 属性,或接受 URL形式的参数。同时,它要比一个较「完整」、利用 LWP [libwww-perl]模组套件的解法,例如 http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/xurl.gz这个程式,快上一百倍。

--------------------------------------------------------------------------------

如何从 user端上传资料?如何在另一台机器上开一个档案?

如果是 HTML表格的话,您可以使用 multipart/form-data的编码格式。 CGI.pm(可自 CPAN取得)中的 start_multipart_form()这个 method 就是为此设计的,它和 startform()这个 method 是两回事。

--------------------------------------------------------------------------------

如何在 HTML中做 pop-up menu(跳出式选单)?

用 和 这两个标签。 CGI.pm模组(可由 CPAN取得)对这个 widget【此指跳出式选单这个介面成分】还有许多其他的介面成分都有支援【即有制作动态标签的函式】,其中有些是以巧妙模拟的方 式达成。

--------------------------------------------------------------------------------

如何抓 HTML档案?

有一个方法是,如果您的系统上装有 lynx一类的文字模式的 HTML浏览器的话,那麽可以这麽做:

$html_code = `lynx -source $url`;

$text_data = `lynx -dump $url`;

收录在 CPAN里的 libwww-perl (LWP)模组则提供了更强的方法来做这件事。它不但可钻过 proxies,而且也不需要 lynx:

# print HTML from a URL

use LWP::Simple;

getprint "http://www.sn.no/libwww-perl/";;

# print ASCII from HTML from a URL

use LWP::Simple;

use HTML::Parse;

use HTML::FormatText;

my ($html, $ascii);

$html = get("http://www.perl.com/";);

defined $html

or die "Can't fetch HTML from http://www.perl.com/";;

$ascii = HTML::FormatText->new->format(parse_html($html));

print $ascii;

--------------------------------------------------------------------------------

如何解开或产生 Web上那些冠 %的码?

以下是一个解码的实例:

$string = "http://altavista.digital.com/cgi-bin/query?pg=q&;what=news&fmt=.&q=%2Bcgi-bin+%2Bperl.exe";

$string =~ s/%([a-fA-F0-9]{2})/chr(hex($1))/ge;

编码比较困难一点,因为您不能盲目地把所有非字母数字的字元 (\W)都一律转换成十六进位的跳脱码。很重要的是有特殊意义的字元,如 / 和 ? 便不可以 转换。要做得正确,最简单的方法大概是使用现成的 URI::Escape模组,而不要重新发明轮子。这个模组是 libwww-perl 套件 (LWP)的一部分,可自 CPAN取得。

--------------------------------------------------------------------------------

如何【将 requests】转向到另一页去?

在您的回应中不要使用 Content-Type这个标头,相反地,用 Location: 这个标头。按正式规定,应当 URL: 才是正确的标头。因此 CGI.pm模组(可 由CPAN取得)两个标头都送:

Location: http://www.domain.com/newpage

URI: http://www.domain.com/newpage

要注意的是,由於 servers采用「最高效率化」的运作方式,故在这些标头中如 果使用相对式的 URLs可能会产生奇怪的後果。

--------------------------------------------------------------------------------

如何替网页加上密码?

不一定,要看情况。您需要读您 server的使用手册,或者查查看上头所列的几个 FAQs。

--------------------------------------------------------------------------------

要怎麽用 Perl来编辑 .htpasswd和 .htgroup这两个档案?

HTTPD::UserAdmin 和 HTTPD::GroupAdmin等模组为这些档案提供了统一的物件导向介面,尽管这些档案可能以各种不同的格式储存。这些资料库可能是纯文字格式、 dbm、Berkeley DB或任何 DBI相容的资料库驱动程式 (drivers)。 HTTPD::UserAdmin支援`Basic' 和 `Digest'这两个认证模式所用的档案。以下是 一例:

use HTTPD::UserAdmin ();

HTTPD::UserAdmin

->new(DB => "/foo/.htpasswd")

->add($username => $password);

--------------------------------------------------------------------------------

如何防范使用者藉由填我的 CGI表格来做坏事?

阅读 CGI security FAQ,(可在 http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq.html取得),还有 Perl CGI FAQ,在 http://www.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html 。

简单一句话:使用 tainting(沾腥?)这项功能(详见 perlsec )。它会让所有不在您的 script中、来路不明的资料(譬如, CGI参数)无法放到 eval 或 system等呼叫中使用。除了使用 tainting之外,绝对不要使用单一参数 的方式下参数给 system()或 exec(),而应将欲执行的指令及其参数放在一个序列或阵列里面,再传给 system()或 exec(),这样便可避免 globbing【即被 shell先做解译】。

--------------------------------------------------------------------------------

如何解读、萃取 email标头资料?

如果您只需要一个「快而脏」的解法的话,您可以试试这个从再版的 ``Programming Perl''第 222页中拿出来的例子:

$/ = '';

$header = ;

$header =~ s/\n\s+/ /g; #将延续行合并成单行

%head = ( UNIX_FROM_LINE, split /^([-\w]+):\s*/m, $header );

譬如说,您若想保留所有 Received栏位资料的话【因 Received栏位通常不止一个】,这个解法便不太行了。一个完整的解法是使用收录在 CPAN的 Mail::Header模组( MailTools 套件的一部分)。

--------------------------------------------------------------------------------

如何解译 CGI表格?

很多人忍不住要自己写程式来处理这部分的工作,所以您们大概都看过一大堆其中有 $ENV{CONTENT_LENGTH} 和 $ENV{QUERY_STRING}的程式码。没错,这麽 写是可以行得通,但事实上也有很多在网路上出没的这类程式根本不能用!

请不要忍不住去重新发明轮子【译者:这是英文的说法 (reinventing the wheels),也就是浪费时间做人家做过的事的意思】。请改用 CGI.pm或 CGI_Lite.pm(可自 CPAN取得)。如果您被困在无模组的 perl1 .. perl4的土地上,您可以试看看 cgi-lib.pl(可至 http://www.bio.cam.ac.uk/web/form.html取得)。

--------------------------------------------------------------------------------

如何验证 email位址?

无法度。

如果没有寄封信到一个位址去试试看它会不会弹回来(即使是这麽做您还得面对停顿的问题),您是无法确定一个位址是否真的存在的。即使您套用 email 标头的标准规格来做检查的依据,您还是有可能会遇到问题,因为有些送得到的位址并不 符合 RFC-822(电子邮件标头的标准)的规定,但有些符合标准的位址却无法投 递。

许多人试图用一个简单的正规表示式,例如 /^[\w.-]+\@([\w.-]\.)+\w+$/来消除一些通常是无效的 email位址。不过,这样做也把很多合格的位址给一起滤掉了,而且对测试一个位址有没有希望投递成功完全没有帮助,所以在此建议大家不要这麽做;不过您可以看看: http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/ckaddr.gz。这个 script真的彻底地依据所有的 RFC规定来做检验(除了内嵌式 comments外),同时会排除一些您可能不会想送信去的位址(如 Bill Clinton【美国柯林顿总统】或您的 postmaster),然後它会确定位址中的主机名称可在 DNS中找得到。这个 script 跑起来不是很快,但至少有效。

不少 CGI scripts的作者使用另一个替代的方案:用一个简单的正规表示式,(如上头的那个)。如果一个位址能让这个式子对得上的话,那麽就接受这个位址。如果这个位址对不上这个式子的话,便再向使用者讯问,以确定她们填入的这个位 址正确无误。

--------------------------------------------------------------------------------

如何解 MIME/BASE64字串?

MIME-tools套件(可自 CPAN取得)不但可处理这个问题而且有许多其他的功能。有了这个套件,解 BASE64码就变得像这麽容易:

use MIME::base64;

$decoded = decode_base64($encoded);

一个比较直接的解法是先做一点简单的转译,然後使用 unpack()这个函数的 ``u'' 格式:

tr#A-Za-z0-9+/##cd; #去除非 base64字元

tr#A-Za-z0-9+/# -_#; #转换成 uu码格式

$len = pack("c", 32 + 0.75*length); #计算长度字元

print unpack("u", $len . $_); # uu解码後 print

--------------------------------------------------------------------------------

如何根据使用者帐户名称自动合成 email位址?

在支援 getpwuid【UNIX系统呼叫】、 $add('From', 'gnat@frii.com');

$header->add('Subject', 'Testing');

$header->add('To', 'gnat@frii.com');

#制作本文

$body = 'This is a test, ignore';

#产生 mail物件

$mail = new Mail::Internet(undef, Header => $header, Body => \[$body]);

#送出

$mail->smtpsend or die;

--------------------------------------------------------------------------------

如何找出我的主机名/网域名/IP位址?

长久以来许多 code都很草率地直接呼叫 `hostname`这个程式来取得主机名。 虽然这麽做很方便,但也同时增加了移植到其他平台上的困难。这是一个很典型的 例子,在方便和可移植性之间作抉择,不论选哪一边,必须付出一些牺牲和代价。

Sys::Hostname这个模组(标准 perl发行的一部分)可用来取得机器的名字,然後您便可利用 gethostbyname()这个系统呼叫来找出该机的 IP位址了(假定您的 DNS 运作正常)。

use Socket;

use Sys::Hostname;

my $host = hostname();

my $addr = inet_ntoa(scalar(gethostbyname($name || 'localhost')));

至少在 Unix底下,取得 DNS网域名最简单的方法大概要算是直接从 /etc/resolv.conf这个档案里面找。当然,这麽做的前提是 resolv.conf这个档 案的设定必须照惯例的格式,还有就是这个档案必先存在才行。

(Perl在非 Unix系统下尚需要一有效的方法来测出机器和网域名)

--------------------------------------------------------------------------------

如何抓新闻讨论群的文章或群组名录?

使用 Net::NNTP或 News::NNTPClient模组,两者皆可自 CPAN下载。这些模组 让抓群组名录这类的差事变得这麽容易:

perl -MNews::NNTPClient

-e 'print News::NNTPClient->;new->list("newsgroups")'

--------------------------------------------------------------------------------

如何抓/丢 FTP档案?

LWP::Simple模组(可自 CPAN下载)可以抓,但不能丢档案。 Net::FTP模组(也可自 CPAN下载)虽比较复杂,但可用来丢、也能抓档案。

--------------------------------------------------------------------------------

如何用 Perl做 RPC?

有一个 DCE::RPC模组正在发展阶段(但尚未完成)。一旦完成後它会随着 DCE-Perl这个套件发行(可由 CPAN 下载)。至於 ONC::RPC这样的模组则还没听说有人在发展。

--------------------------------------------------------------------------------

作者及版权事宜

Copyright (c) 1997 Tom Christiansen and Nathan Torkington.着作权所有, All rights reserved。有关使用、(转)发行事宜,详见 perlfaq 。

中译版着作权所有:萧百龄及两只老虎工作室。本中译版遵守并使用与原文版相同 的使用条款发行。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有