简体   繁体   English

与其他 rest 客户端相比,在 flutter 发布请求中获得不同的响应

[英]getting different response in flutter post request compared to other rest clients

I'm getting different response from the api if call it using flutter Response in YARC REST Client:如果在 YARC REST 客户端中使用 flutter 响应调用它,我会从 api 得到不同的响应: 在此处输入图像描述 在此处输入图像描述 Response in Flutter: Flutter 中的响应: 在此处输入图像描述 The first line is the json sent to the api.第一行是 json 发送到 api。

The error showm in api log: api 日志中显示的错误:

Failed to parse json data from JsonRpc@::ffff:192.168.0.243: Error: illegal value at Line: 0, Column: 0

Main.dart:主.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);
                },
                )
            )

          ],
        ),
      ),
    );
  }
}



This is my first flutter project so I'm still not completely sure of how stuff work.这是我的第一个 flutter 项目,所以我仍然不完全确定它是如何工作的。

Update: It is working fine on YARC, postman and python.更新:它在 YARC、postman 和 python 上运行良好。 It is not working on advanced rest client(arc) and flutter.它不适用于高级 rest 客户端(弧)和 flutter。

use json.deode(response.body) to print and parse json使用 json.deode(response.body) 打印和解析 json

This is caused by a bug in the Hyperion server.这是由 Hyperion 服务器中的错误引起的。 It is treating the HTTP headers as case sensitive.它将 HTTP 接头视为区分大小写。 (This violates the relevant RFC.) Dart always forces the headers to lower case. (这违反了相关的 RFC。) Dart 总是强制标题为小写。 In this case the server is looking for Content-Length , but Dart sends content-length , which the server (incorrectly) doesn't figure out are the same thing.在这种情况下,服务器正在寻找Content-Length ,但 Dart 发送content-length ,服务器(错误地)不认为是同一件事。

Luckily there's a way in Dart to force the case of headers, but you have to write a few more lines of boiler-plate.幸运的是,在 Dart 中有一种方法可以强制使用标题的大小写,但是您必须多写几行样板代码。 Here's a working example:这是一个工作示例:

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM