与其他客户端相比,在 flutter post 请求中得到不同的响应
getting different response in flutter post request compared to other rest clients
如果使用 flutter 调用它,我会从 api 得到不同的响应
YARC REST 客户端中的响应:
颤振中的响应:
第一行是 json 发送到 api.
api 日志中的错误显示:
Failed to parse json data from JsonRpc@::ffff:192.168.0.243: Error: illegal value at Line: 0, Column: 0
Main.dart:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:smart_home/user_model.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
Future req(String col) async{
var data = json.encode({
"command":"color",
"color":[255,0,0],
"priority":50,
"origin":"My Fancy App"
});
print(data);
final response = await http.post(Uri.parse("http://192.168.0.151:8090/json-rpc"),
body: data,
headers: {"Authorization": "token 46a2032e-da1b-4c20-b690-27413aa43589"}
);
print(response.body);
if(response.statusCode==200){
final String responseString = response.body;
return userModelFromJson(responseString);
}
else
return null;
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var selectedvalue = null;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: Text("Led Controls",
style: TextStyle(fontSize: 25),),
),
body: Column(
children: [
Container(
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
child: DropdownButton(
value: selectedvalue,
items: <String>['Static color', 'Effects'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (value) {
setState(() {
selectedvalue=value.toString();
});
},
isExpanded: true,
hint: Text("Select Operating Mode"),
),
),
if(selectedvalue=="Static color") Container(
//padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
child: ColorPicker(
pickerColor: Colors.white,
paletteType: PaletteType.hueWheel,
onColorChanged: (x) async{
String col="[${x.red.toString()},${x.green.toString()},${x.blue.toString()}]";
final UserModel? resp = await req(col);
//print(resp!.success);
},
)
)
],
),
),
);
}
}
这是我的第一个 flutter 项目,所以我仍然不完全确定这些东西是如何工作的。
更新:
它在 YARC、邮递员和 python 上运行良好。它不适用于高级休息客户端 (arc) 和 flutter。
这是由 Hyperion 服务器中的错误引起的。它将 HTTP headers 视为区分大小写。 (这违反了相关的 RFC。)Dart 总是强制 headers 为小写。在这种情况下,服务器正在寻找 Content-Length
,但 Dart 发送 content-length
,服务器(错误地)没有弄清楚是同一件事。
幸运的是,Dart 中有一种方法可以强制 headers 的大小写,但你必须多写几行 boiler-plate。这是一个工作示例:
import 'dart:convert';
import 'dart:io';
void main() async {
// encode the post body as JSON and then UTF8 bytes
final dataBytes = utf8.encode(json.encode({
'command': 'color',
'color': [255, 0, 0],
'priority': 50,
'origin': 'My Dart App'
}));
// use the low level HttpClient to get control of the header case
final client = HttpClient();
final request = await client.post('127.0.0.1', 8090, '/json-rpc');
// manually add the content length header to preserve its case
request.headers.add(
'Content-Length', // note the upper case string - try it with lower case (spoiler it fails)
dataBytes.length.toString(),
preserveHeaderCase: true,
);
// optional - add other headers (e.g. Auth) here
// request.headers.add(/*some other header*/);
// send the body bytes
request.add(dataBytes);
// 'close' the request to send it, and get a response
final response = await request.close();
print(response.statusCode);
// turn the streamed response back to a string so that it can be parsed as JSON
final responseBody = await response.transform(utf8.decoder).join();
print(responseBody);
// close the client (or re-use it if you prefer)
client.close();
}
如果使用 flutter 调用它,我会从 api 得到不同的响应
YARC REST 客户端中的响应:
api 日志中的错误显示:
Failed to parse json data from JsonRpc@::ffff:192.168.0.243: Error: illegal value at Line: 0, Column: 0
Main.dart:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:smart_home/user_model.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
Future req(String col) async{
var data = json.encode({
"command":"color",
"color":[255,0,0],
"priority":50,
"origin":"My Fancy App"
});
print(data);
final response = await http.post(Uri.parse("http://192.168.0.151:8090/json-rpc"),
body: data,
headers: {"Authorization": "token 46a2032e-da1b-4c20-b690-27413aa43589"}
);
print(response.body);
if(response.statusCode==200){
final String responseString = response.body;
return userModelFromJson(responseString);
}
else
return null;
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var selectedvalue = null;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: Text("Led Controls",
style: TextStyle(fontSize: 25),),
),
body: Column(
children: [
Container(
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
child: DropdownButton(
value: selectedvalue,
items: <String>['Static color', 'Effects'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (value) {
setState(() {
selectedvalue=value.toString();
});
},
isExpanded: true,
hint: Text("Select Operating Mode"),
),
),
if(selectedvalue=="Static color") Container(
//padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
child: ColorPicker(
pickerColor: Colors.white,
paletteType: PaletteType.hueWheel,
onColorChanged: (x) async{
String col="[${x.red.toString()},${x.green.toString()},${x.blue.toString()}]";
final UserModel? resp = await req(col);
//print(resp!.success);
},
)
)
],
),
),
);
}
}
这是我的第一个 flutter 项目,所以我仍然不完全确定这些东西是如何工作的。
更新: 它在 YARC、邮递员和 python 上运行良好。它不适用于高级休息客户端 (arc) 和 flutter。
这是由 Hyperion 服务器中的错误引起的。它将 HTTP headers 视为区分大小写。 (这违反了相关的 RFC。)Dart 总是强制 headers 为小写。在这种情况下,服务器正在寻找 Content-Length
,但 Dart 发送 content-length
,服务器(错误地)没有弄清楚是同一件事。
幸运的是,Dart 中有一种方法可以强制 headers 的大小写,但你必须多写几行 boiler-plate。这是一个工作示例:
import 'dart:convert';
import 'dart:io';
void main() async {
// encode the post body as JSON and then UTF8 bytes
final dataBytes = utf8.encode(json.encode({
'command': 'color',
'color': [255, 0, 0],
'priority': 50,
'origin': 'My Dart App'
}));
// use the low level HttpClient to get control of the header case
final client = HttpClient();
final request = await client.post('127.0.0.1', 8090, '/json-rpc');
// manually add the content length header to preserve its case
request.headers.add(
'Content-Length', // note the upper case string - try it with lower case (spoiler it fails)
dataBytes.length.toString(),
preserveHeaderCase: true,
);
// optional - add other headers (e.g. Auth) here
// request.headers.add(/*some other header*/);
// send the body bytes
request.add(dataBytes);
// 'close' the request to send it, and get a response
final response = await request.close();
print(response.statusCode);
// turn the streamed response back to a string so that it can be parsed as JSON
final responseBody = await response.transform(utf8.decoder).join();
print(responseBody);
// close the client (or re-use it if you prefer)
client.close();
}