Perl HTTP请求JSON参数报错,Python正常,求排查问题
Perl代码PUT请求报错排查
问题场景
以下Perl代码执行后返回类型错误,但相同逻辑的Python代码却能正常运行:
Perl报错代码
use strict; use Data::Dumper; use LWP::UserAgent; use JSON; my $token = 'my token'; my $ua = LWP::UserAgent->new; my $req = HTTP::Request->new(PUT => "endpoint"); $req->header( 'Authorization' => "Bearer $token" ); $req->content_type('application/json'); $req->content('{"text":"whiteboard"}'); my $res = $ua->request($req); if ($res->is_success) { my $content = $res->decoded_content; my $fromjson = from_json($content); print Dumper $fromjson->{'results'}; } else { print $res->status_line, "\n"; print $res->content, "\n"; }
错误信息
{"detail":[{"loc":["body"],"msg":"str type expected","type":"type_error.str"}]}
正常运行的Python代码
import requests import os import json url = 'endpoint' token='my token' headers = { "Authorization": "Bearer "+token[:-1], "Content-type" : "application/json" } res=requests.put(url, json='{"text":"whiteboard"}', headers=headers) #res=requests.put(url, json='test string', headers=headers) # this also works print('Response Content:\n',res)
问题原因与解决
核心问题是服务端期望请求体是纯字符串类型,而非JSON对象结构,但你的Perl代码发送的是一个JSON对象的字符串表示。
看Python代码的逻辑:requests库的json参数如果传入字符串,会直接把这个字符串作为请求体发送(跳过JSON序列化步骤),所以即使你传'{"text":"whiteboard"}'这种看起来像JSON的字符串,服务端收到的就是这个原始字符串,刚好符合它的要求。
而Perl代码里,你发送的'{"text":"whiteboard"}'是一个JSON对象,服务端解析时发现这是个对象而非字符串,所以抛出类型错误。
解决方法
根据服务端实际需求二选一:
- 如果服务端期望纯文本字符串
修改Perl代码的Content-Type和请求内容:
# 调整Content-Type为纯文本类型 $req->content_type('text/plain'); # 直接发送服务端需要的字符串内容 $req->content('whiteboard');
- 如果服务端需要application/json类型,但期望字符串值
发送字符串的JSON表示(即把字符串用双引号包裹):
$req->content_type('application/json'); # 发送字符串的JSON格式,而非JSON对象 $req->content('"whiteboard"');
内容的提问来源于stack exchange,提问作者Jean
相关产品推荐
相关产品推荐

