如何在flatter中使用表单数据生成http post?

如何在flatter中使用表单数据生成http post?,http,flutter,dart,form-data,Http,Flutter,Dart,Form Data,我正在尝试执行http post请求,我需要将主体指定为表单数据,因为服务器不会将请求视为原始数据 这就是我正在做的: 导入'dart:convert'; 进口“包装:颤振/材料.省道”; 将“package:http/http.dart”导入为http; void main()=>runApp(MyApp()); 类MyApp扩展了StatefulWidget{ @凌驾 _MyAppState createState()=>\u MyAppState(); } 类MyAppState扩展了状态

我正在尝试执行http post请求,我需要将主体指定为表单数据,因为服务器不会将请求视为原始数据

这就是我正在做的:

导入'dart:convert';
进口“包装:颤振/材料.省道”;
将“package:http/http.dart”导入为http;
void main()=>runApp(MyApp());
类MyApp扩展了StatefulWidget{
@凌驾
_MyAppState createState()=>\u MyAppState();
}
类MyAppState扩展了状态{
postTest()异步{
最终用户识别码https://na57.salesforce.com/services/oauth2/token';
var requestBody={
“授权类型”:“密码”,
“客户id”:“3MVG9dZJodJWITSviqdj3EnW.LRZ81MBUGBQGIXXXD6U7MRU2NOES8BHFOFYNW”NVKPHLF2EZDBNY0RPHQL,
“客户机密”:“42E131F37E4E05313646E1ED1D3788D76192EBECA7486D15BDB8408B9726B42”,
“用户名”:”example@mail.com.us',
“密码”:“ABC1234563Af88jesKxPLVirJRW8wXvj3D”
};
http.Response-Response=等待http.post(
乌里,
body:json.encode(requestBody),
);
打印(响应.正文);
}
@凌驾
小部件构建(构建上下文){
返回材料PP(
家庭:集装箱(
儿童:中心(
孩子:升起按钮(
子项:文本('Press Here'),
已按下:(){
后测();
},
),
),
),
);
}
}
这是实际的反应:

{
    "error": "unsupported_grant_type",
    "error_description": "grant type not supported"
}
{
    "access_token": "00D0b000000Bb08!AR8AQO.s8mAGXCbwV77FXNLQqc2vtl8g6_16miVbgWlQMsuNHsaf2IGLUwnMVXBOfAj19iznhqhwlPOi4tagvf7FFgiJJgoi",
    "instance_url": "https://na57.salesforce.com",
    "id": "https://login.salesforce.com/id/00D0b000000Bb08EAC/0050b000005nstiAAA",
    "token_type": "Bearer",
    "issued_at": "1567993324968",
    "signature": "1+Zd/dSh9i7Moh2U0nFJLdXkVHqPlPVU6emwdYzXDPk="
}

这是预期的反应:

{
    "error": "unsupported_grant_type",
    "error_description": "grant type not supported"
}
{
    "access_token": "00D0b000000Bb08!AR8AQO.s8mAGXCbwV77FXNLQqc2vtl8g6_16miVbgWlQMsuNHsaf2IGLUwnMVXBOfAj19iznhqhwlPOi4tagvf7FFgiJJgoi",
    "instance_url": "https://na57.salesforce.com",
    "id": "https://login.salesforce.com/id/00D0b000000Bb08EAC/0050b000005nstiAAA",
    "token_type": "Bearer",
    "issued_at": "1567993324968",
    "signature": "1+Zd/dSh9i7Moh2U0nFJLdXkVHqPlPVU6emwdYzXDPk="
}

您可以在postman上测试这一点,在原始(您得到实际响应)和表单数据(您得到预期响应)之间切换身体

PS:标题是由客户端工具创建的临时标题。

您能试试这个吗

    String url = 'https://myendpoint.com';
      Map<String, String> headers = {
"Content-Type": "application/x-www-form-urlencoded"    
"Content-type": "application/json"};
      String json = '{"grant_type":"password",
        "username":"myuser@mail.com",
        "password":"123456"}';
      // make POST request
      Response response = await post(url, headers: headers, body: json);
      // check the status code for the result
      int statusCode = response.statusCode;
      // this API passes back the id of the new item added to the body
      String body = response.body;
String url='1!'https://myendpoint.com';
映射头={
“内容类型”:“应用程序/x-www-form-urlencoded”
“内容类型”:“应用程序/json”};
字符串json='{“授权类型”:“密码”,
“用户名”:”myuser@mail.com",
“密码”:“123456”}';
//发帖
Response-Response=wait-post(url,headers:headers,body:json);
//检查结果的状态代码
int statusCode=response.statusCode;
//此API传回添加到主体的新项的id
字符串体=response.body;

改用Map,因为http包中的body只有3种类型:String、List或Map。试试这个:

final uri = 'https://na57.salesforce.com/services/oauth2/token';
var map = new Map<String, dynamic>();
map['grant_type'] = 'password';
map['client_id'] = '3MVG9dZJodJWITSviqdj3EnW.LrZ81MbuGBqgIxxxdD6u7Mru2NOEs8bHFoFyNw_nVKPhlF2EzDbNYI0rphQL';
map['client_secret'] = '42E131F37E4E05313646E1ED1D3788D76192EBECA7486D15BDDB8408B9726B42';
map['username'] = 'example@mail.com.us';
map['password'] = 'ABC1234563Af88jesKxPLVirJRW8wXvj3D';

http.Response response = await http.post(
    uri,
    body: map,
);
final-uri=
编辑1(这适用于代码登录流):

从以下位置尝试使用“FormData”:

import 'package:dio/dio.dart';

FormData formData = new FormData.fromMap(dataMap);

retrofitClient.getToken(formData).then((response){//--handle respnse--});
“客户端”来自程序包
改装:^1.0.1+1

有一个dart包dio
它就像一个符咒,我用它作为标准来做http请求。
请阅读关于使用dio软件包发送表单数据的说明

import 'package:dio/dio.dart';    

postData(Map<String, dynamic> body)async{    
var dio = Dio();
try {
      FormData formData = new FormData.fromMap(body);
      var response = await dio.post(url, data: formData);
      return response.data;
    } catch (e) {
      print(e);
    }
}
import'包:dio/dio.dart';
postData(映射体)异步{
var-dio=dio();
试一试{
FormData FormData=新建FormData.fromMap(主体);
var response=wait dio.post(url,数据:formData);
返回响应数据;
}捕获(e){
印刷品(e);
}
}

使用POSTMAN测试查询并获取格式非常有用。这允许您查看是否确实需要设置标题。请参见下面的示例。我希望这会有帮助,而且不会太多

import 'dart:convert';
import 'package:http/http.dart';

class RegisterUser{    
  String fullname;
  String phonenumber;
  String emailaddress;
  String password;
  Map data;    
  RegisterUser({this.fullname, this.phonenumber, this.emailaddress, this.password});    
  Future<void> registeruseraction() async {    
    String url = 'https://api.url.com/';
    Response response = await post(url, body: {
      'fullname' : fullname,
      'phonenumber' : phonenumber,
      'emailaddress' : emailaddress,
      'password' : password
    });    
    print(response.body);
    data = jsonDecode(response.body);    
  }    
}
导入'dart:convert';
导入“包:http/http.dart”;
类注册器{
字符串全名;
字符串电话号码;
字符串电子邮件地址;
字符串密码;
地图数据;
RegisterUser({this.fullname,this.phonenumber,this.emailaddress,this.password});
Future registeruseraction()异步{
字符串url='0https://api.url.com/';
响应=等待发布(url,正文:{
“全名”:全名,
“phonenumber”:phonenumber,
“emailaddress”:emailaddress,
“密码”:密码
});    
打印(响应.正文);
data=jsonDecode(response.body);
}    
}

使用MultipartRequest类

多部分/表单数据请求会自动将内容类型头设置为多部分/表单数据

此值将覆盖用户设置的任何值

请参阅pub.dev文档

例如:

 Map<String, String> requestBody = <String,String>{
     'field1':value1
  };
 Map<String, String> headers= <String,String>{
     'Authorization':'Basic ${base64Encode(utf8.encode('user:password'))}'
  };

  var uri = Uri.parse('http://localhost.com');
  var request = http.MultipartRequest('POST', uri)
    ..headers.addAll(headers) //if u have headers, basic auth, token bearer... Else remove line
    ..fields.addAll(requestBody);
  var response = await request.send();
  final respStr = await response.stream.bytesToString();
  return jsonDecode(respStr);
Map requestBody={
“字段1”:值1
};
映射头={
“授权”:“基本${base64Encode(utf8.encode('user:password'))}”
};
var uri=uri.parse('http://localhost.com');
var request=http.MultipartRequest('POST',uri)
..headers.addAll(headers)//如果您有头、基本身份验证、令牌承载。。。否则,请删除该行
..fields.addAll(请求主体);
var response=wait request.send();
final respStr=wait response.stream.bytesToString();
返回jsonDecode(respStr);

希望这有帮助

那么,您想将正文作为表单数据发送,对吗?也许你可以试试这个?对我来说这是工作

postTest() async {
    final uri = 'https://na57.salesforce.com/services/oauth2/token';
    var requestBody = {
      'grant_type':'password',
      'client_id':'3MVG9dZJodJWITSviqdj3EnW.LrZ81MbuGBqgIxxxdD6u7Mru2NOEs8bHFoFyNw_nVKPhlF2EzDbNYI0rphQL',
      'client_secret':'42E131F37E4E05313646E1ED1D3788D76192EBECA7486D15BDDB8408B9726B42',
      'username':'example@mail.com.us',
      'password':'ABC1234563Af88jesKxPLVirJRW8wXvj3D'
    };

    http.Response response = await http.post(
        uri,
        body: requestBody,
    );

    print(response.body);
  }


HTTP还不支持
表单数据


改用。它会自己处理一切

使用或不使用标题没有区别,我的重点是如何将正文作为表单数据发送我也更新了我的问题,现在您可以测试更接近我真实情况的内容。@M.Massula我认为在颤振中,没有任何选项可以使用表单数据请求。只可能,您可以使用json传递数据。这在头字符串之间缺少一个逗号。不起作用,post方法接受无论如何使用json对象。如果主体是一个映射,则使用编码将其编码为表单字段。请求的内容类型将设置为“application/x-www-form-urlencoded”。似乎使用地图的行为更自然,就像来自