簡體   English   中英

當我使用Perl的REST :: Client發送POST請求,而不使用Perl的LWP :: UserAgent或Python發送POST請求時,為什么會收到“ 405:方法不允許”的信息?

[英]Why do I get “405: Method Not Allowed” when I send a POST request with Perl's REST::Client, but not with Perl's LWP::UserAgent or Python?

當我使用Perl的REST::Client發送POST請求時,得到以下響應:

405: Method Not Allowed

但是,當我使用Perl的LWP::UserAgent或Python的Requests向相同的URL發送POST請求時,會收到“成功”響應。 GET請求可與REST::Client和Python一起使用。

我怎樣才能解決這個問題?


以下是使用REST::Client的代碼(返回HTTP 405):

use REST::Client;
use JSON;
$header = {
    'Auth' => '04211b77df',
    'Accept' => 'application/json',
    'Content-type' => 'application/json'
};

%body = (
    'sid' => '001',
    'pid' => 'c7b3d83',
    'file' => [
        {
            'name' => 'file1.txt',
            'location' => 'folderA'
        },
        {
            'name' => 'file2.txt',
            'location' => 'folderB'
        }
    ]
);

$client = REST::Client->new();
$client->POST('URL', encode_json(\%body), $header);

這是使用LWP::UserAgent的代碼(返回HTTP 200):

#!/use/bin/perl -w
use strict;
use LWP::UserAgent;
use Data::Dumper;
use JSON;

my $ua = LWP::UserAgent->new; 
my $req = HTTP::Request->new(POST => 'URL');

$req->header('Auth' => '04211b77df');
$req->header('Content-type' => 'application/json');
$req->header('Accept' => 'application/json');

my %body = (
    'sid' => '001',
    'pid' => 'c7b3d83',
    'file' => [
        {
            'name' => 'file1.txt',
            'location' => 'folderA'
        },
        {
            'name' => 'file2.txt',
            'location' => 'folderB'
        }
    ]
);
$req->content(encode_json(\%body));
$ua->request($req);

這是Python代碼(返回HTTP 200):

import requests, json, sys
headers = {
    'Auth': '04211b77df'
    'Accept': 'application/json'
    'Content-type': 'application/json'
}
data={
    'sid': '001',
    'pid': 'c7b3d83',
    'file': [
        {
            'name': 'file1.txt',
            'location': 'folderA'
        },
        {
            'name': 'file2.txt',
            'location': 'folderB'
        }
    ]
}

requests.request('POST', 'URL', data=data, headers=headers)

您的REST :: Client代碼和您的LWP :: UserAgent代碼生成幾乎相同的請求。*但是,使用LWP :: UserAgent的REST :: Client在$ua->simple_request()使用$ua->simple_request()發送請求,而您的LWP :: UserAgent代碼使用$ua->request()

根據文檔

request()的區別在於simple_request()不會嘗試處理重定向或身份驗證響應。

我猜認證是引起問題的原因。 我還猜測您正在使用的API不需要對GET請求進行身份驗證,因為您說的是與REST :: Client一起使用的。


要解決此問題,請在構造函數中將follow選項設置為1

my $client = REST::Client->new(follow => 1);

或調用setFollow方法:

my $client = REST::Client->new();
$client->setFollow(1);

這將正確處理身份驗證響應,但也會跟隨重定向。 不幸的是,您不能單獨設置重定向和身份驗證的行為,這是一個長期存在的錯誤


*唯一的區別是REST :: Client添加了一個Content-length標頭,我認為這並不重要。

發送前轉儲REST :: Client請求:

$VAR1 = bless( { 
                 '_content' => '{"sid":"001","pid":"c7b3d83","file":[{"location":"folderA","name":"file1.txt"},{"location":"folderB","name":"file2.txt"}]}',
                 '_uri' => bless( do{\(my $o = 'http://www.example.com')}, 'URI::http' ),
                 '_headers' => bless( { 
                                        'auth' => '04211b77df',
                                        'content-type' => 'application/json',
                                        'accept' => 'application/json',
                                        'content-length' => 122,
                                        '::std_case' => { 
                                                          'auth' => 'Auth'
                                                        }
                                      }, 'HTTP::Headers' ),
                 '_method' => 'POST'
               }, 'HTTP::Request' );

發送之前轉儲LWP :: UserAgent請求:

$VAR1 = bless( { 
                 '_content' => '{"sid":"001","pid":"c7b3d83","file":[{"location":"folderA","name":"file1.txt"},{"location":"folderB","name":"file2.txt"}]}',
                 '_uri' => bless( do{\(my $o = 'http://www.example.com')}, 'URI::http' ),
                 '_headers' => bless( { 
                                        'auth' => '04211b77df',
                                        'content-type' => 'application/json',
                                        'accept' => 'application/json',
                                        '::std_case' => { 
                                                          'auth' => 'Auth'
                                                        }
                                      }, 'HTTP::Headers' ),
                 '_method' => 'POST'
               }, 'HTTP::Request' );

實際發送請求時,還會有其他細微差別,例如用戶代理字符串,但我認為它們與您的問題無關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM