Hello,
I need to post some data to a distant API. But it looks like the API wants Content-Type: application/json but I'm sending a Content-Type: application/json; charset=utf-8.
I forced the headers:
Map<String, String> headers = {
HttpHeaders.AUTHORIZATION: 'Bearer ${this._token}',
HttpHeaders.CONTENT_TYPE: 'application/json'
};
but keep sending with the charset. Is there a possibility to remove it from the Content Typeheader ?
Thanks
Looks like charset ("encoding") is always added on Content-Type in case it's not set:
https://github.com/dart-lang/http/blob/master/lib/src/request.dart#L84-L92
For good measure I checked with the RFCs and it seems the "parameter" part of the Content-Type value is either mandatory or optional depending on the particular MIME type/subtype:
https://tools.ietf.org/html/rfc2045#section-5
As far as I can tell the 'application/json' MIME type does explicitly _not_ define a "charset" parameter:
https://www.iana.org/assignments/media-types/application/json
Ultimately this points to the http package being buggy. I don't think it's valid to blindly add parameters to just any MIME type. In fact, while probably done with good intentions, silently adding anything should probably be avoided.
Work-around: Set the body first _(this sets default headers)_, then set the headers.
I have the same problem, however the above solution did not work in my case.
For clarity, this is what worked for me:
Request request = new Request('POST', Uri.parse(url));
request.body = body;
request.headers['content-type'] = 'text/xml';
request.headers['accept'] = 'text/xml';
I encountered the same issue, but @jheyne workaround didn't work for me.
We should be able to write request.encoding = null.
Good afternoon,
I have the same problem.
The lib is automatically placing charset = utf-8 in the request header, so I'm having trouble consuming some REST WebServices, making it impossible to use it.
The issue is already open for one year.
Is there no solution to such a problem?
Thank you.
Cristian Regazzo
Has anyone solved this yet?
It seems to be more of a problem when there encoding more complex types such as
class MyClass {
ClassOne class1;
ClassTwo class2;
}
I've tried jsonEncode, I've used the JSONSerializable package, setting the body before headers, just as @jheyne mentioned. I don't understand why the HttpClient encodes to UTF-8 by default. Either way, life is very difficult right now. I've even added UTF-8 encoding to my .NET server and still nothing :(
Marc
Has anybody found a solution to this yet?
I'm running into the same problem with my REST endpoint refusing to accept my requests because it doesn't expect the charset property to be set.
For now I have a local solution by copying the Package locally and modifying lib/src/request.dart to remove the lines that add charset if it's not there: (based on @cskau-g 's comment earlier)
request.dart
```
91 set body(String value) {
92 bodyBytes = encoding.encode(value);
93 var contentType = _contentType;
94 if (contentType == null) {
95 _contentType = MediaType('text', 'plain', {'charset': encoding.name});
You can find that code excerpt at https://github.com/dart-lang/http/blob/master/lib/src/request.dart#L84-L92
@jefioliveira tried to made a pull request for a similar change but it was understandably denied because a lot of applications probably rely on the current auto-addition of charset. It's been six months since then.
Would it be possible to just add an additional optional parameter to the Request class that would tell it not to add charset?
@jheyne solution worked for me.
I had problem with the API server not accepting "charset". @jheyne's solution worked perfectly.
@jheyne's answer worked for me.
This is my code.
import 'package:http/http.dart';
final String url = "your api url";
try {
final httpClient = HttpClient();
final request = await httpClient.postUrl(Uri.parse(url));
// headers
request.headers.set('Authorization', 'Bearer $AuthToken');
<b>request.headers.contentType = new ContentType("application", "json");</b>
// body
request.add(
utf8.encode(
jsonEncode(
<String, String>{
'somebody': somebody,
},
),
),
);
final response = await request.close();
if (response.statusCode == 200) {
final responseBody = await response.transform(utf8.decoder).join();
final result = Model.fromJson(json.decode(responseBody));
}
} on TimeoutException catch (_) {
//print
} on SocketException catch (_) {
//print
}
This is a complete non sense : why is the charset added even if we provide the content-type ? The user input should override the default values, not the opposite !
Are there any updates regarding this topic?
Has anyone managed to remove the 'charset=utf8' from the http header or found another solution? My backend also won't accept the request if the charset is specified.
Please specify 'application/vnd.api+json' instead of 'application/vnd.api+json; charset=utf-8' for the Content-Type header value.
Also I use Json Api Specification for Flutter. I cannot set the body first like @jheyne mentioned because the library makes the request.
final httpHandler = LoggingHttpHandler(DartHttp(httpClient),
onRequest: (r) => print('${r.method} ${r.uri} ${r.headers}'),
onResponse: (r) => print('${r.statusCode} ${r.body}'));
final client = JsonApiClient(httpHandler);
var headers = {
'Authorization': 'Bearer $jwtToken',
'Content-Type': 'application/vnd.api+json'
};
client.fetchResourceAt(Uri.parse('$urlTesting$urlPath/code/$invitationCodeString'),headers: headers);
@snowLimit I faced the same issues and decided to use this library https://pub.dev/packages/dio. It's very similar but more flexible and has a lot of interesting features 馃槈
Most helpful comment
For clarity, this is what worked for me:
Request request = new Request('POST', Uri.parse(url));
request.body = body;
request.headers['content-type'] = 'text/xml';
request.headers['accept'] = 'text/xml';