问题
I'm trying to process a HTTP request in Flutter/Dart (in this case using the SEARCH method to filter some files on a WebDAV server (Nextcloud)) need to send XML data in the body of the request.
[x] Can execute the comand using cURL on terminal with the --data parameter:
curl -u user:pass -X SEARCH 'https://host123.com.br/remote.php/dav' -H "content-Type: text/xml" --data '<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/wprech</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:and><d:or><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/png</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/jpg</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>video/mp4</d:literal></d:eq></d:or></d:and></d:where><d:orderby/></d:basicsearch></d:searchrequest>'
[x] Also works via Postman app:
[ ] Can't do this request with xml body using Flutter/Dart. All other HTTP requests of this project we used the DIO pkg, and it works fine, but the problem is. to send the xml body with it. The closest code is bellow:
void _list() async {
final prefs = await SharedPreferences.getInstance();
var us = prefs.getString('id') ?? '';
var sn = prefs.getString('password') ?? '';
String basicAuth = 'Basic ' + base64Encode(utf8.encode('$us:$sn'));
try {
Dio dio = new Dio();
dio.options.method = 'SEARCH';
dio.options.responseType = ResponseType.plain;
dio.options.headers = {
HttpHeaders.authorizationHeader: basicAuth,
'content-Type': 'text/xml'
};
String data =
'<?xml version="1.0" encoding="UTF-8"?><d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"><d:basicsearch><d:select><d:prop><d:displayname/></d:prop></d:select><d:from><d:scope><d:href>/files/wprech</d:href><d:depth>infinity</d:depth></d:scope></d:from><d:where><d:and><d:or><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/png</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>image/jpg</d:literal></d:eq><d:eq><d:prop><d:getcontenttype/></d:prop><d:literal>video/mp4</d:literal></d:eq></d:or></d:and></d:where><d:orderby/></d:basicsearch></d:searchrequest>';
Response response = await dio.request(
"https://host123.com.br/remote.php/dav",
data: data);
print(response);
} catch (e) {
print(e);
}}
Server responses vary between 400, 404, 500 e 501, depending how it's sent:
I/flutter ( 6767): DioError [DioErrorType.RESPONSE]: Http status error [400]
Any help? :)
回答1:
Experiment with a simpler package:http
version.
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
main() async {
var username = 'foo';
var password = 'B@r!';
var credential = base64.encode(utf8.encode('$username:$password'));
var client = http.IOClient();
var request = http.Request(
'SEARCH',
Uri.parse('https://host123.com.br/remote.php/dav'),
);
request.headers.addAll({
HttpHeaders.authorizationHeader: 'Basic $credential',
'content-type': 'text/xml' // or text/xml;charset=utf-8
});
var xml = '<?xml version="1.0" encoding="UTF-8"?>...';
// either
request.body = xml;
// which will encode the string to bytes, and modify the content-type header, adding the encoding
// or
// request.bodyBytes = utf8.encode(xml);
// which gives you complete control over the character encoding
var streamedResponse = await client.send(request);
print(streamedResponse.statusCode);
var responseBody =
await streamedResponse.stream.transform(utf8.decoder).join();
print(responseBody);
client.close();
}
来源:https://stackoverflow.com/questions/58399365/flutter-http-request-send-using-xml-body