【问题标题】:Perl CGI: get request not working unless URL is hard-codedPerl CGI:获取请求不起作用,除非 URL 是硬编码的
【发布时间】:2012-12-25 07:36:33
【问题描述】:

我试图在 URL 获取请求期间识别两个字符串之间的差异(使用 LWP::Simple)。
我有一个网址,比如http://www.example.com?param1=x&param2=y&param3=z
我确保所有空白输入也得到处理,但此时这无关紧要,因为我确保所有参数都完全相同。
此外,硬编码的 URL 是从生成的 URL 复制和粘贴的。
当我执行以下操作时,此 URL 有效:

my $url = "http://www.example.com?param1=x&param2=y&param3=z";
my $content = get($url);

然而,当我根据用户提供的参数构建 URL 时,get 请求不起作用(错误:来自站点的 500)。
我通过打印出来比较了这两个 URL,发现差异为零。我已尝试删除所有潜在的不可见字符。

生成的代码和静态字符串的输出,假设用户输入与静态字符串相同(这是我确保要做的):

http://www.example.com?param1=x&param2=y&param3=z
http://www.example.com?param1=x&param2=y&param3=z

我假设打印输出会删除我看不到的字符。 我也遵循了http://www.perlmonks.org/?node_id=882590 的解决方案,它指出了差异,但我不知道为什么,因为我根本看不到任何东西。
有没有人遇到过这个问题?如果我需要澄清任何事情或需要提供其他信息,请告诉我。




编辑:问题和解决方案
因此,在使用 mob 的建议来识别差异后,我发现生成的 URL 中有一个空字符,它没有在输出中打印出来。那就是:
http://www.example.com?param1=x&param2=y&param3=z实际上是
http://www.example.com?param1=x&param2=y&param3=\000z
我使用了一个简单的正则表达式:$url =~ s/\000//g; 来删除该(以及任何其他)空值。

【问题讨论】:

  • 你能提供你的代码来解析用户输入,同时输出显示差异
  • 我只是通过 POST 传递值并按名称获取它们。事实证明,其中一个 POST 值添加了一个 NULL 序列,而我什至没有考虑这一点。

标签: string perl url cgi get-request


【解决方案1】:

使用数据序列化函数检查字符串中是否存在隐藏字符。

$url1 = "http://www.example.com?param1=x&param2=y";
$url2 = "http://www.example.com?param1=x&param2=y\0";
$url3 = "http://www.example.com?param1=x&param2=y\n";

use JSON;
print JSON->new->pretty(1)->encode( [$url1,$url2,$url3] );
# Result:
# [
#   "http://www.example.com?param1=x&param2=y",
#   "http://www.example.com?param1=x&param2=y\u0000",
#   "http://www.example.com?param1=x&param2=y\n"
# ]


use Data::Dumper;
$Data::Dumper::Useqq = 1;
print Dumper($url1,$url2,$url3);
# Result:
# $VAR1 = "http://www.example.com?param1=x&param2=y";
# $VAR2 = "http://www.example.com?param1=x&param2=y\0";
# $VAR3 = "http://www.example.com?param1=x&param2=y\n";

【讨论】:

  • 好吧,多亏了你,我发现了不同之处……也许这是主要问题。在生成的URL中,一个参数是value=\000989%20Yakima(我打印出来的时候是看不到的。硬编码的是:value=989%20Yakima。进度!
【解决方案2】:

很明显,您构建的字符串与硬编码的字符串不同。如果你写这样的代码

my $ss = 'http://www.example.com?param1=x&param2=y&param3=z';
print join(' ', map " $_", $ss =~ /./g), "\n";
print join(' ', map sprintf('%02X', ord), $ss =~ /./g), "\n";

那么你就可以看到字符串中每个字符的十六进制值,并且可以更准确的比较两者。比如上面的代码输出

 h  t  t  p  :  /  /  w  w  w  .  e  x  a  m  p  l  e  .  c  o  m  ?  p  a  r  a  m  1  =  x  &  p  a  r  a  m  2  =  y  &  p  a  r  a  m  3  =  z
68 74 74 70 3A 2F 2F 77 77 77 2E 65 78 61 6D 70 6C 65 2E 63 6F 6D 3F 70 61 72 61 6D 31 3D 78 26 70 61 72 61 6D 32 3D 79 26 70 61 72 61 6D 33 3D 7A

【讨论】:

  • 有趣的是,硬编码的那个是从生成的那个不起作用的那个复制粘贴过来的。
  • 嗯,到目前为止,这表明存在直接的差异。当我找到问题/解决方案时,我会回复你们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多