[英]Send form with Python requests the same way as Perl LWP::UserAgent does
[英]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.