首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl - LWP API Post

Perl - LWP API Post
EN

Stack Overflow用户
提问于 2014-03-21 12:52:59
回答 2查看 3.3K关注 0票数 2

我试图发布一个新的项目到一个上市网站使用LWP。清单网站提供了一个示例,说明如何发布数据,但使用PHP,因此我尝试在Perl中再现解决方案。

这是PHP示例。

代码语言:javascript
复制
$postData = array('type'   => 'fixedPrice',
                  'item'   => array(
                      'id_country'         => 0,
                      'id_category'        => 80,
                      'fixed_price'        => '1.00', 
                      'currency'           => 'EUR',
                      'title'              => 'My title',
                      'personal_reference' => 'My personal ref',
));

//RESOURCE CALL WITH POST METHOD

$url = 'http://correct.server.address/item?token=MyPersonalToken';
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_POST, true);
curl_setopt ($ch, CURLOPT_POSTFIELDS, http_build_query($postData) );
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$xml_response  = curl_exec($ch);

我的Perl解决方案:

代码语言:javascript
复制
#!/usr/bin/perl

### Module requests ###

use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request::Common;
use XML::LibXML;
use Data::Dumper;

### Make Request to get the session Token ###

my $url = "http://correct.server.address/seller";
my $api = "APIKEY";

my $userAgent = LWP::UserAgent->new();
my $request = HTTP::Request->new(POST => $url . "?apikey=" . $api);
my $response = $userAgent->request($request);

### Display error if request to server fails ###

unless ($response->is_success) {
    print "Content-type: text/html\n\n";
    print "Error: " . $response->status_line;
    exit;
}

### Assign response xml to $xml_token ###

my $xml_token = $response->content;

### Parse XML through XML::LibXML module ###

my $parser = XML::LibXML->new();
my $tree = $parser->parse_string($xml_token);
my $root = $tree->getDocumentElement;
my $token = $root->getElementsByTagName('token');

### Make Request to add Item - PROBLEM STARTS HERE ###

my $postURL = "http://correct.server.address/item" . "?token=" . $token;

my %item_data = (type => "fixedPrice",
                item => {
                    id_country => "0",
                    id_category => "728",
                    fixed_price => "1.00",
                    currency => "GBP",
                    title => "Test item",
                    personal_reference => "12345"
                }
            );

my $userAgentReq2 = LWP::UserAgent->new();
my $requestReq2 = HTTP::Request->new(POST => $postURL);
$requestReq2->header(content_type => 'multipart/form-data');
$requestReq2->content(\%item_data);
my $responseReq2 = $userAgentReq2->request($requestReq2);

### Display error if request to server fails ###

unless ($responseReq2->is_success) {

    print "Content-type: text/html\n\n";
    print "<p>Error Message: " . $responseReq2->status_line;
    print "</p><p>Output of test data sent: \n";
    print Dumper(\%item_data);
    print "</p><p>Dumped Response: \n";
    print Dumper($responseReq2);
    print "</p><p>\n";
    print "Token: $token\n";
    print "</p><p>\n";
    print "Response: " . $responseReq2->as_string;
    print "</p>\n";
    exit;
}

### Assign response xml to $xml_responseReq2 ###

my $xml_responseReq2 = $responseReq2->content;

### Display Token ###

print "Content-type: text/html\n\n";
print "<p>Response: $xml_responseReq2</p>\n";
print Dumper($responseReq2);
exit;

检索会话令牌的第一个post请求正常工作,并接收令牌。然而,我的第二个帖子请求试图添加该项目失败。

这是被抛出的回应:

代码语言:javascript
复制
$VAR1 = bless( {
                 '_content' => 'Not a SCALAR reference at /usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm line 203.
',
                 '_rc' => 500,
                 '_headers' => bless( {
                                        'client-warning' => 'Internal response',
                                        'client-date' => 'Fri, 21 Mar 2014 12:13:34 GMT',
                                        'content-type' => 'text/plain',
                                        '::std_case' => {
                                                          'client-warning' => 'Client-Warning',
                                                          'client-date' => 'Client-Date'
                                                        }
                                      }, 'HTTP::Headers' ),
                 '_msg' => 'Not a SCALAR reference',
                 '_request' => bless( {
                                        '_content' => {
                                                        'item' => {
                                                                    'currency' => 'GBP',
                                                                    'id_category' => '728',
                                                                    'id_country' => '0',
                                                                    'personal_reference' => '12345',
                                                                    'title' => 'Test item',
                                                                    'fixed_price' => '1.00'
                                                                  },
                                                        'type' => 'fixedPrice'
                                                      },
                                        '_uri' => bless( do{\(my $o = 'http://correct.server.address/item?token=986aee823d54a7c2d50651c1b272c455')}, 'URI::http' ),
                                        '_headers' => bless( {
                                                               'user-agent' => 'libwww-perl/6.05',
                                                               'content-type' => 'multipart/form-data'
                                                             }, 'HTTP::Headers' ),
                                        '_method' => 'POST'
                                      }, 'HTTP::Request' )
               }, 'HTTP::Response' );

请有人帮我知道我哪里出了问题,非常感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-30 11:40:37

下面的内容似乎实现了您想要的结果。

代码语言:javascript
复制
my %item_data = (type => "fixedPrice",
                'item[id_country]' => "0",
                'item[id_category]' => "728",
                'item[fixed_price]' => "1.00",
                'item[currency]' => "GBP",
                'item[title]' => "Test item",
                'item[personal_reference]' => "12345"
        );

my $userAgentReq2 = LWP::UserAgent->new();
my $responseReq2 = $userAgentReq2->post($postURL,[%item_data]);
票数 1
EN

Stack Overflow用户

发布于 2014-03-21 14:31:36

PHP允许您创建自动反序列化为嵌套结构的POST变量;例如,您可以有名为item[0]item[1]等表单字段,这些字段将以值数组的形式出现在服务器端的PHP脚本中。但是HTTP没有任何数组的概念;post数据是简单的键和值对。

示例客户端PHP代码试图构建一个嵌套数组结构,PHP的curl接口将自动转换为HTTP字段名。我已经有一百万年没有做任何PHP了,但是我认为字段名最终会是item[0][id_country]item[0][id_category]等等。这就是PHP如何“欺骗”HTTP,将复杂的结构放入POST中。

Perl的LWP库不支持以这种方式从嵌套结构中构建字段名。这就是为什么你要犯这个错误:

而不是/usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm第203行的标量引用。‘

在POST参数中,item键指向一个散列引用,但是LWP希望那里只看到一个普通的标量或标量引用。

因此,您需要将LWP POST参数更改为如下所示。(如果这不完全正确,您可以在PHP代码上使用HTTP嗅探器来确定它生成的实际字段名。)

代码语言:javascript
复制
my %item_data = (type => "fixedPrice",
                 'item[0][id_country]' => "0",
                 'item[0][id_category]' => "728",
                 'item[0][fixed_price]' => "1.00",
                 'item[0][currency]' => "GBP",
                 'item[0][title]' => "Test item",
                 'item[0][personal_reference]' => "12345"
            );
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22559356

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档