Dart POST Response missing Headers - flutter

I guess I'll move this to the top because none of what's been said so far addresses my question. There are some response headers in Postman that I don't get in Dart. I need to access those values in order for my application to work. How do I get access to the Headers that are in Postman but Dart doesn't seem to have?
I'm using the Dart/Flutter http package in general it does everything I need it to. What I've run into trouble recently is that it doesn't return some non-standard headers as part of a post request. For example, I'm trying to make the following request:
POST https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4/Patient?_format=json&_pretty=false
Headers: {"Content-Type": "application/fhir+json", "Authorization": "Bearer $BearerToken"}
Body: {"resourceType":"Patient","identifier":[{"type":{"coding":[{"system":"http://hl7.org/fhir/sid/us-ssn","code":"SB"}]
},"system":"urn:oid:2.16.840.1.113883.4.1","value":"444114567"}],"name":[{"use":"usual","text":"Derrick
Lin","family":"Lin","given":["Derrick"]}],"gender":"male","birthDate":"1973-06-03"}
Note, this request succeeds. It returns a Status Code of 201 and I've checked the server and the Patient is successfully created. However, the Response headers are:
{
"cache-control": "no-cache,no-store",
"content-length": 0,
"content-type": "application/fhir+json; charset=utf-8",
"expires": -1,
"pragma": "no-cache"
}
Now, I've tried stopping this request right before posting so I ensure I have all of the correct parameters. And if I copy the same values into Postman, I still recieve a Status of 201, but I receive these as the Response Headers:
{
"Expires": -1,
"Location": "Patient/eoc0yXThvv5aQEdz-kjaSWQ3",
"Allow-Control-Allow-Headers": "origin, authorization, accept, content-type, x-requested-with, Epic-User-ID, Epic-User-IDType, Epic-Client-ID, soapaction, Epic-MyChartUser-ID, Epic-MyChartUser-IDType",
"Allow-Control-Allow-Methods": "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS",
"Allow-Control-Allow-Origin": "*",
"Allow-Control-Allow-Credentials": true,
"cache-control": "no-cache,no-store",
"content-length": 0,
"content-type": "application/fhir+json; charset=utf-8",
"pragma": "no-cache"
}
I need access to these extra headers in dart, specifically the "Location" header. To answer one of the questions below, as far as the code for creating the request, the first is going through the some Oauth2 Code to get the Bearer token. After that, it's calling a POST method on a class that Extends http.Client.
#override
Future<http.Response> post(Uri url,
{Map<String, String>? headers,
Object? body,
Encoding? encoding}) async =>
await http.post(
url,
headers: await newHeaders(headers),
body: body,
encoding: encoding,
);
#override
Future<Map<String, String>> newHeaders(Map<String, String>? headers) async {
headers ??= <String, String>{};
if (client?.credentials.accessToken != null) {
headers['Authorization'] = 'Bearer ${client!.credentials.accessToken}';
}
headers.addAll(authHeaders ?? <String, String>{});
return headers;
}
And again, the request succeeds, it successfully posts the resource, the resource is created, and I get a 201 status code showing it was created. What I don't get is the full set of response headers.
Does anyone have any idea if I'm creating the request incorrectly, if this is something wrong with the http package, or something wrong with the Dart SDK?

There are CORS headers for allowing cross domain access to a web browser:
"Allow-Control-Allow-Headers": "origin, authorization, accept, content-type, x-requested-with, Epic-User-ID, Epic-User-IDType, Epic-Client-ID, soapaction, Epic-MyChartUser-ID, Epic-MyChartUser-IDType",
"Allow-Control-Allow-Methods": "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS",
"Allow-Control-Allow-Origin": "*",
"Allow-Control-Allow-Credentials": true,
This is related to redirecting a web browser to a new location after creating a resource.
"Location": "Patient/eoc0yXThvv5aQEdz-kjaSWQ3",

Related

Request blocked by CORS policy: Header field is not allowed by Access-Control-Allow-Headers

I am using Axios to make a POST request with the following headers:
let reqConf = {
headers: {
'x-xsrf-token': '....',
'Content-Type': 'Application/json',
'Access-Control-Request-Headers': 'content-type',
'Access-Control-Allow-Headers': 'Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Access-Control-Allow-Headers, x-xsrf-token'
}
}
I make a post call like so: const response = await axios.post(url, request, reqConf )' I get the following error message: Request blocked by CORS policy: Request Header x-xsrf-token field is not allowed by Access-Control-Allow-Headers`, but if I remove that header from my request I still get the same error but for other headers such as Content-Type.
I have modified the server config to allow Header set Access-Control-Allow-Origin "*". I have set Access-Control-Allow-Headers with all of my headers and my OPTIONS call returns 200 in browser. Is there something else I am missing in my request?

How to add API key to Axios post request for mailchimp

I'm trying to set up an axios post request to add members to an audience list, but I can't figure out how to add the API key (keeps giving error 401: 'Your request did not include an API key.'). I've tried a bunch of things in the "Authorization" header, like what I put below (also: "Bearer ${mailchimpKey}", "${mailchimpKey}", "Bearer ${mailchimpKey}", "Basic ${mailchimpKey}", and probably more...).
I also don't know what the "username" would be, but "any" worked when I tested the API elsewhere.
Does anyone know how I should set this up?
axios
.post(
`https://${server}.api.mailchimp.com/3.0/lists/${list_id}/members`,
{
email_address: email,
status: "subscribed",
},
{
"User-Agent": "Request-Promise",
Connection: "keep-alive",
Authorization: `Basic any:${mailchimpKey}`,
// Testing on localhost
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type",
}
)
If your intention is to use HTTP Basic authentication, just use the Axios auth config option
axios.post(
`https://${server}.api.mailchimp.com/3.0/lists/${encodeURIComponent(list_id)}/members`,
{
email_address: email,
status: "subscribed",
},
{
auth: {
username: "anystring",
password: mailchimpKey
},
headers: { // personally, I wouldn't add any extra headers
"User-agent": "Request-Promise"
}
}
)
HTTP Basic auth headers look like
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
where the string after "Basic" is the Base64 encoded "username:password" string. Axios provides the auth option as a convenience so you don't need to encode the string yourself.
Some other problems you had were:
Adding request headers outside the headers config option
Attempting to send Access-Control-Allow-Origin and Access-Control-Allow-Headers as request headers. These are response headers only. Adding them to your request will most likely cause more CORS errors

"Content-Type" and "Content-Encoding" headers in axios

I am using axios#0.21.1 and I want to validate the response headers.
I am unable validate the headers "Content-Type" and "Content-Encoding" from a GET response.
"Content-Type": No matter what content-type i pass in request, the content-type in response is always application/JSON.
Example Code Snippet:
if (<token is present>) {
request.headers = {
authorization : 'Bearer ${token}'
}
} else {
config.auth = {}
}
config.headers = Object.assign(config.header, {
'content-type': application/<custom content>,
'accept-encoding': 'gzip, deflate, br'
}
await axios.get(endPoint, config)
.then(response => {
return response
}*
When i am checking response.header, i see that content-type is showing as "application/json" instead of the custom type. But when i hit the same url in POSTMAN i could see that content-type is as expected.
Content-Encoding: I want to validate the content-encoding in the response, but what i learnt is axios does not return content-encoding header in the response and when i check their github, they are asking to use axios.interceptors. I tried using interceptors but still i am not seeing the header in response. But this header is present in response when i try in POSTMAN. There have been some solution say CORS needs to be enabled in server side. I am strictly asking it from QA point of view because we cannot enable CORS in server side.
Any help is highly appreciable.
Try:
axios.post(your-url, {
headers: {
'Content-Encoding': 'gzip'
}
})
or
axios.post(your-url, {
headers: {
'Accept-Encoding': 'gzip',
}
})
This is by design: https://axios-http.com/docs/req_config
I also ran into this and couldn't find a solution. Ended up using node-fetch instead.

Sending int and boolean at body of http post method in flutter

Hi I have a http post as
final http.Response response = await client.post(
'http://someurl/',
headers: {
HttpHeaders.contentTypeHeader: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": token
},
body: {
"isItTake": false,
"servisID": 1
}
);
But when I try this post method I get "Unhandled Exception: type 'bool' is not a subtype of type 'String' in type cast". I can change the API to expect string but I wonder if there is a work around to send int or boolean.
Note that When I send a similar request on postman everything is fine.
Edit:
Postman:
POST /someendpoint/ HTTP/1.1
Host: somehost
Authorization: Token sometoken
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 20582fd0-c980-2d0d-fb2f-3bdd87d767f5 \
{
"isItTake": false,
"servisID": 1
}
Try sending the request body values as Strings and see if that works. I've faced this issue before with type mismatch with the request bodies of http requests and I'm not quite sure as to why it throws exceptions like that even though the documentation for the api clearly specifies the type for each value in the request body. Try this:
final http.Response response = await client.post(
'http://someurl/',
headers: {
HttpHeaders.contentTypeHeader: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": token
},
body: {
"isItTake": 'false',
"servisID": '1'
}
);
Or in case if you have your values in some bool and int variables:
final http.Response response = await client.post(
'http://someurl/',
headers: {
HttpHeaders.contentTypeHeader: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": token
},
body: {
"isItTake": isItTake.toString(),
"servisID": servisID.toString()
}
);
Use String encoded = json.encode(theMap); then post encoded. If you need a particular character encoding (e.g. utf-8) then further encode the string using utf8.encode(encoded) and post the resulting byte array. (The second step should be unnecessary for utf-8 as I think that is the default.)
It's worth considering what the 3 variants do:
List<int> - sends an opaque byte array
String encodes the string into bytes using a character encoding - and sends the byte array
Map<String, String> - encodes the string key/value pairs in
x-www-form-urlencoded and sends that.
If you want to send more complex data then you need to convert it into one of the above (and the server needs to know how to decode it). That's where the content-type header is useful. Ultimately, the server receives a byte array and converts it back into, for example, a string, or some json, or a set of form fields, or an image. It knows how to do this based on the header and any specified encoding.
Complete Credit: Source

Paypal UNSUPPORTED_MEDIA_TYPE

I am trying to get an access token from paypal's authorization api.
When I make post request to the api I get UNSUPPORTED_MEDIA_TYPE i.e. 415 response.
Below is the snippet that I used.
const auth = await fetch(PAYPAL_OAUTH_API, {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${ basicAuth }`
},
body: JSON.stringify({"grant_type": "client_credentials"})
});
I have fixed my issue by setting Content-Type to application/x-www-form-urlencoded.
My guess is paypal accepts only application/x-www-form-urlencoded for authorization api.
I ran into same issue, and the solution is following (using Postman):
Select POST
Add Token into Authorization, type is Bearer-Token
Select Content-Type: application/json in headers
Use RAW as body, and in TEXT dropdown, select JSON (application/JSON)
Copy body as raw object and change info accordingly.
Step 4 and 5 are what solved the error, you must send raw json object.