问题
Right, so I've been working on something which requires basic authentication through headers, and passing some variables via HTTP Post. This is a terminal app.
This is what my code looks like:
import 'package:http/http.dart' as http;
import 'dart:io';
void main() {
var url = "http://httpbin.org/post";
var client = new http.Client();
var request = new http.Request('POST', Uri.parse(url));
var body = {'content':'this is a test', 'email':'john@doe.com', 'number':'441276300056'};
request.headers[HttpHeaders.CONTENT_TYPE] = 'application/json; charset=utf-8';
request.headers[HttpHeaders.AUTHORIZATION] = 'Basic 021215421fbe4b0d27f:e74b71bbce';
request.body = body;
var future = client.send(request).then((response) => response.stream.bytesToString().then((value) => print(value.toString()))).catchError((error) => print(error.toString()));
}
I'm using httpbin as an echo server, so it tells me what I'm passing in. My code works correctly if I don't pass a body, or if I pass a string as the body.
Obviously that's because the body attribute in http.Request only accepts strings, and I'm trying to pass a map to it.
I could convert that to a string, and it would probably work, but I still think my code could be improved. Not from a syntax point of view, or from how it's handling the future, but I'm not certain using http.dart is the right thing to do.
Could someone point me in the right direction?
Thanks in advance.
回答1:
JSON is a String. You need to encode your map to JSON and pass it as a String.
You can use bodyFields
instead of body
to pass a Map.
This way your content-type
is fixed to "application/x-www-form-urlencoded"
.
The DartDoc for post
says:
/// If [body] is a Map, it's encoded as form fields using [encoding]. The
/// content-type of the request will be set to
/// `"application/x-www-form-urlencoded"`; this cannot be overridden.
I was able to send JSON data this way a while ago
return new http.Client()
.post(url, headers: {'Content-type': 'application/json'},
body: JSON.encoder.convert({"distinct": "users","key": "account","query": {"active":true}}))
.then((http.Response r) => r.body)
.whenComplete(() => print('completed'));
EDIT
import 'package:http/http.dart' as http;
import 'dart:io';
void main() {
var url = "http://httpbin.org/post";
var client = new http.Client();
var request = new http.Request('POST', Uri.parse(url));
var body = {'content':'this is a test', 'email':'john@doe.com', 'number':'441276300056'};
// request.headers[HttpHeaders.CONTENT_TYPE] = 'application/json; charset=utf-8';
request.headers[HttpHeaders.AUTHORIZATION] = 'Basic 021215421fbe4b0d27f:e74b71bbce';
request.bodyFields = body;
var future = client.send(request).then((response)
=> response.stream.bytesToString().then((value)
=> print(value.toString()))).catchError((error) => print(error.toString()));
}
produces
{
"args": {},
"data": "",
"files": {},
"form": {
"content": "this is a test",
"email": "john@doe.com",
"number": "441276300056"
},
"headers": {
"Accept-Encoding": "gzip",
"Authorization": "Basic 021215421fbe4b0d27f:e74b71bbce",
"Connection": "close",
"Content-Length": "63",
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"Host": "httpbin.org",
"User-Agent": "Dart/1.5 (dart:io)",
"X-Request-Id": "b108713b-d746-49de-b9c2-61823a93f629"
},
"json": null,
"origin": "91.118.62.43",
"url": "http://httpbin.org/post"
}
来源:https://stackoverflow.com/questions/24183716/doing-an-http-post-with-headers-and-a-body