【问题标题】:Reuse LWP Useragent object with HTTP POST query in a for/while loop在 for/while 循环中通过 HTTP POST 查询重用 LWP Useragent 对象
【发布时间】:2021-06-29 15:11:30
【问题描述】:

我正在使用 LWP Useragent 通过基本授权进行多次 POST 调用,其中 POST URL 参数是从 CSV 文件中读取的。这是我的代码:

use strict;
use warnings;

use LWP::UserAgent;
use JSON 'from_json';
use MIME::Base64 'encode_base64';
use Data::Dumper;

my @assets;
my %data;
my $response;
my $csvfile = 'ScrappedData_Coins.csv';
my $dir = "CurrencyImages";

open (my $csv, '<', "$dir/$csvfile") || die "cant open";
foreach (<$csv>) {
   chomp;
   my @currencyfields = split(/\,/);
   push(@assets, \@currencyfields);
}
close $csv;

my $url = 'https://example.org/objects?';

my %options = (         
        "username" =>  'API KEY',
        "password" => '' );  # Password field is left blank
        
my $ua = LWP::UserAgent->new(keep_alive=>1);
$ua->agent("MyApp/0.1");
$ua->default_header(
                    Authorization => 'Basic '. encode_base64( $options{username} . ':' . $options{password} )
);
my $count =0;

foreach my $row (@cryptoassets) {
          
          $response = $ua->post(
                     $url,
                     Content_Type => 'multipart/form-data',
                     Content => {
                           'name'=>${$row}[1],
                           'lang' => 'en',
                           'description' => ${$row}[6],             
                           'parents[0][Objects][id]' => 42100,
                           'Objects[imageFiles][0]' =>[${$row}[4]],
                         }
                  );
         
         if ( $response->is_success ) {
             my $json = eval { from_json( $response->decoded_content ) };
             print Dumper $json;
         }
         else {
          $response->status_line;
          print $response;
         }
}
sleep(2);
}

基本上,我想重用 LWP 对象。为此,我使用keep_alive true 选项创建了一次LWP 对象、其标头和响应对象,以便服务器和客户端之间的连接保持打开状态。但是,服务器的响应不是我想要实现的。一个参数值 ('parents[0][Objects][id]' =&gt; 42100) 似乎没有在 HTTP POST 调用中传递给服务器。事实上,它的行为是随机的,有时传递 parentID 对象值,有时不传递,而所有其他 param 值都正确传递。这是由于重用 LWP 代理对象造成的问题,还是存在其他问题?因为当我进行单个 HTTP POST 调用时,所有参数值都正确传递,而在循环中执行此操作时并非如此。我想拨打 50 多个 POST 电话。

【问题讨论】:

  • “一个参数值 (...) 似乎没有在 HTTP POST 调用中传递给服务器。” - 你如何检查传递了哪些参数?您是否真的检查了实际请求,或者您只是假设这是您看到的某些错误的原因,但真正的原因实际上可能是其他原因。
  • 我没有检查真实请求并假设异常行为与指定的参数值相关,而其余参数上传。你能告诉我如何通过 POST 检查我发送的 HTTP 请求吗?
  • “你能告诉我如何检查我通过 POST 发送的 HTTP 请求吗?” - 请参阅 find out how an LWP request was sent “over the wire”UserAgent Debugging Made Easy 了解如何执行此操作。
  • 我自己找到了解决方案。我在 POST 方法中在 hashref 中传递表单数据。我把它改成arrayref,问题就解决了。我确实尝试了 LWP Console Logger,但问题没有解决,或者我无法正确分析 HTTP 请求日志。另外,我收到“[由 LWP::ConsoleLogger 编辑。不知道如何显示 multipart/form-data;boundary=xYzZY-”并且不知道如何生成。

标签: perl lwp-useragent


【解决方案1】:

重用用户代理对象不是我的第一个怀疑。

Mojo::UserAgent 在您发出请求时返回一个完整的事务对象。即使在我发送请求之后,我也很容易检查请求。这是让我对 LWP 感到恼火的巨大好处之一。你可以这样做,但你必须先分解工作以形成请求。

在这种情况下,首先创建查询哈希,然后在发送之前查看它。它拥有您所期望的一切吗?

然后,查看请求。请求是否与您刚刚提供的哈希匹配?

另外,什么时候出错?是第一个请求没问题但第二个请求失败,还是几个没问题然后一个失败?

您可以尝试 httpbin.org,而不是针对您的实时系统进行测试。您可以通过各种方式向它发送请求

use Mojo::UserAgent;
use Mojo::Util qw(dumper);

my $hash = { ... };
say dumper( $hash );

my $ua = Mojo::UserAgent->new;
$ua->on( prepare => sub { ... } );  # add default headers, etc

my $tx = $ua->post( $url, form => $hash );

say "Request: " . $tx->req->to_string;

【讨论】:

  • 我自己找到了解决方案。我在 POST 方法中在 hashref 中传递表单数据。我把它改成arrayref,问题就解决了。我在 CPAN 页面上阅读了如何将数据传递给 POST 方法。
  • 因此,重用 LWP 对象不是问题。
【解决方案2】:

我自己找到了解决方案。我正在使用 hashref 将表单参数数据(键/值对)传递给 POST 方法。我把它改成arrayref,问题就解决了。我阅读了如何在 CPAN 页面上将数据传递给 POST 方法。因此,正如@brian d foy 所指出的,重用 LWP 对象不是问题。

CPAN HTTP LWP::UserAgent API

CPAN HTTP Request Common API

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多