在 for/while 循环中将 LWP Useragent object 与 HTTP POST 查询一起使用

Reuse LWP Useragent object with HTTP POST query in a for/while loop

我正在使用 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 object。为此,我正在创建 LWP object、它的 headers 和响应 objects 一次,并选择 keep_alive true,以便服务器和服务器之间的连接保持打开状态客户。然而,服务器的响应并不是我想要达到的。一个参数值 ('parents[0][Objects][id]' => 42100) 似乎没有在 HTTP POST 调用中传递到服务器。事实上,它的行为是随机的,有时传递 parentID object 值,有时不传递,而所有其他参数值都正确传递。这是由于重用 LWP 代理 object 造成的问题还是存在其他问题?因为当我进行单个 HTTP POST 调用时,所有参数值都已正确传递,而在循环中执行此操作时情况并非如此。我想拨打 50+ POST 个电话。

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

Mojo::UserAgent returns 当你发出请求时一个完整的事务对象。即使在我发送请求后,我也很容易检查请求。这是让我对 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;

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

CPAN HTTP LWP::UserAgent API

CPAN HTTP Request Common API