API always error 408 - Invalid Data Type Sent - http

I really don't know what happen with this error (I mean by, is this related to the Flutter or Dart or the package that I used or the API that I used). In a nutshell, it always giving me back error code 408 - Invalid data type sent from my flutter App, while I COMPLETELY could done it in Postman and been tried it with PHP.
I just wanna call a normal POST request to my payment gateway API (I use Midtrans).
Here is my result:
From Postman
From my app in Flutter within VS Code
What am I doing wrong? I am completely has no clue about this.
I will give the detail below for anyone who want to try a simple call to this API so you can reproduce this.
Endpoint
https://api.sandbox.midtrans.com/v2/charge
Body
"payment_type": "bank_transfer",
"bank_transfer": {
"bank": "permata",
"va_number": "1234567890"
},
"transaction_details": {
"order_id": "order-101b-{{2020-11-0222rrd324dzz}}",
"gross_amount": 44000
},
"customer_details": {
"email": "richie.permana#gmail.com",
"first_name": "Richie",
"last_name": "Permana",
"phone": "+6281 1234 1234"
},
"item_details": [
{
"id": "item01",
"price": 21000,
"quantity": 1,
"name": "Schema Programmer"
},
{
"id": "item02",
"price": 23000,
"quantity": 1,
"name": "Ayam Xoxoxo"
}
]
}
This is the header
{
'content-type': 'application/json',
'accept': 'application/json',
'authorization':
'Basic U0ItTWlkLXNlcnZlci1kNnJNbGp5ZDBKSDgyOEhBT28tSWkxM0E=',
'cache-control': 'no-cache'
}
My Dart Function Snippet
Future _makePayment() async {
String url = "https://api.sandbox.midtrans.com/v2/charge";
final Map<String, String> header = {
'content-type': 'application/json',
'accept': 'application/json',
'authorization':
'Basic U0ItTWlkLXNlcnZlci1kNnJNbGp5ZDBKSDgyOEhBT28tSWkxM0E=',
'cache-control': 'no-cache'
};
var json = jsonEncode({
"payment_type": "bank_transfer",
"bank_transfer": {"bank": "permata", "va_number": "1234567890"},
"transaction_details": {
"order_id": "order-101b-{{2020-11-0222rrddzz557}}",
"gross_amount": 44000
},
"customer_details": {
"email": "richie#example.com",
"first_name": "Richie",
"last_name": "Permana",
"phone": "+6281 1234 1234"
},
"item_details": [
{
"id": "item01",
"price": 21000,
"quantity": 1,
"name": "Schema Programmer"
},
{"id": "item02", "price": 23000, "quantity": 1, "name": "Ayam Xoxoxo"}
]
});
Response response = await post(
url,
headers: header,
body: json,
);
var res = jsonDecode(response.body);
print(
"payloadddded =>> ${json.runtimeType}\n");
if (res['status_code'] == 201) {
print("ngeheeeee berhasil MIDTRAANSS =>> ${res['status_code']}");
} else {
print("res full =>> ${response.body}");
print("ape kaden => ${res['status_code']} || terosz => $res");
}
}
Note:
For the body, you may be need put more attention on the order_id because it will return some error if you not change the order_id (yes, think it like any other primary key id).
API Docs: https://api-docs.midtrans.com/
I really appreciate any helps or workaround given.
Thank you very much.

Dart's package:http manipulates the content-type header under the hood. If it does the encoding from string to bytes for you (i.e. if body is a string) then it adds a charset=xxx suffix to the content type - it becomes, for example application/json; charset=utf-8.
Apparently your server is allergic to this. (It shouldn't be, but whatever...). You can prove this using the dart:io http client.
var client = HttpClient();
var request = await client.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json; charset=utf-8');
request.headers.add(
'authorization',
'Basic U0ItTWlkLXNlcnZlci1kNnJNbGp5ZDBKSDgyOEhBT28tSWkxM0E=',
);
request.add(utf8.encode(json));
var response2 = await request.close();
var reply = await response2.transform(utf8.decoder).join();
print(reply);
client.close();
This gives the same 408 error but does not if the charset suffix is removed.
There's a simple solution. Don't allow http to do the encoding for you - do it yourself.
var response = await http.post(
url,
headers: headers,
body: utf8.encode(json),
);
(Your json apparently needs work, because this now complains that the json is invalid, but that's easy to compare with your working postman.)

Related

Flutter Dio post an object with array

I am trying to post a request to api with an object as"
var params = {
"item": "itemx",
"options": [1,2,3],
};
print(params);
try {
Response response = await _dio.post(getAddToCartURL,
queryParameters: params,
options: Options(headers: {
HttpHeaders.contentTypeHeader: "application/json",
}));
} catch (error, stackTrace) {
print("Exception occurred: $error stackTrace: $stackTrace");
return false;
}
Dio sends the object as :
POST /api/add-to-cart/?item=itemx&options%5B%5D=1&options%5B%5D=2&options%5B%5D=3
in which the api recognize it as a bad request.
what is wrong that i am doing here? I have even tried the list as [ "1","2","3"], it is the same.
It all depends on how the API expects it. I would suggest trying to encode it as JSON.
var params = {
"item": "itemx",
"options": jsonEncode([1,2,3]),
};
But sending complex data in query parameters isn't always that easy. Since you are using POST anyway, maybe send a JSON object as body instead of using query parameters.
var params = {
"item": "itemx",
"options": [1,2,3],
};
...
Response response = await _dio.post(getAddToCartURL,
options: Options(headers: {
HttpHeaders.contentTypeHeader: "application/json",
}),
data: jsonEncode(params),
);
another example for any one might be helpful , posting fomr data
var formData = FormData.fromMap({
'data': json.encode(
{'salt': salt, 'placeholder': 'palceholder',
'method_name': 'app_details'})
});
var response = await dio.post(
BaseUrl,
data: formData,
);
the final result of your request is this

Posting Image to Personal Profile Invalid Request Parameters

Unable to share image content through share endpoint, image asset is uploaded through assets API but my request to share API which is copied directly from the example here https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/share-api?context=linkedin/compliance/context#share-content returns an error, invalid parameters in the request body [/Headers] see below details.
Request Headers:
{Authorization: Bearer ***
X-Restli-Protocol-Version: 2.0.0
}
Request Body
{"content":{"contentEntities":[{"entity":"urn:li:digitalmediaAsset:C5622AQEEn3mmqzCb5w"}],"title":"Great Result","landingPageUrl":"https://google.com.au","shareMediaCategory":"IMAGE"},"distribution":{"linkedInDistributionTarget":{}},"owner":"urn:li:person:zzR_UbXjsG","subject":"Great Result","text":{"text":"Great result, couldn't have gone better #realestate"}}
Scopes:
scope=r_emailaddress w_member_social w_organization_social r_basicprofile rw_company_admin rw_organization_admin
Error:
{"serviceErrorCode":100,"message":"Unpermitted fields present in REQUEST_BODY: Data Processing Exception while processing fields [/Headers]","status":403}
It looks like the error message has to do with the headers. Your request body is JSON, but you don't have a Content-Type header set, so this could be the problem:
Content-Type: application/json
Generally, you need a Content-Length header to be sent along with that, but most of the time the client you are using to send the request handles setting that one.
I'm not sure how you're making the request, but here is a fetch() example in JavaScript (make sure you put the correct auth token in the Authorization header):
const url = 'https://api.linkedin.com/v2/shares';
const requestBody = {
"content": {
"contentEntities": [
{
"entity": "urn:li:digitalmediaAsset:C5622AQEEn3mmqzCb5w"
}
],
"title": "Great Result",
"landingPageUrl": "https://google.com.au",
"shareMediaCategory": "IMAGE"
},
"distribution": {
"linkedInDistributionTarget": {}
},
"owner": "urn:li:person:zzR_UbXjsG",
"subject": "Great Result",
"text": {
"text": "Great result, couldn't have gone better #realestate"
}
};
async function makeRequest(url, requestBody) {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ***',
'X-Restli-Protocol-Version': '2.0.0'
},
body: JSON.stringify(requestBody) // body data type must match "Content-Type" header
});
return await response.json(); // parses JSON response into native JavaScript objects
}
// make the actual request
makeRequest(url, requestBody);

http post request with response in angular2 Nativescript

i am new to angular2 native script programming.. i need to post data to a particular url from my app. when i try to post data then get a message on console Response with status: 200 for URL: null. whats the meaning of this message.? and what should i do for successfull post request..?
//my code
let headers = new Headers({ "Content-Type": "application/json" });
let options = new RequestOptions({ headers: headers });
let body =
{
"firstName": "boby",
"lastName": "samuels",
"Location": "UK"
};
this.http.post("http://example.com", JSON.stringify(body), options)
.subscribe(result =>
{
console.log("response : "+result);
}, error =>
{
console.dir(error);
});
please help me out.

Can't convert successful Postman call to Ionic-Native HTTP.post [Ionic 2 ts]

I'm in the process of building an Ionic 2 (ts) app that will send a REST call to the OCR.space API. Going through their examples, I'm able to send a a Base64Image via HTTP.post, but when attempting to send a file via HTTP.Post, I'm met with:
{"ParsedResults":null,"OCRExitCode":0,"IsErroredOnProcessing":false,"ErrorMessage":["Parameter
name 'file' is invalid. Valid parameters:
apikey,url,language,isoverlayrequired,base64image"],"ErrorDetails":null,"ProcessingTimeInMilliseconds":"1"}
I'm guessing it's my formatting of my post request:
HTTP.post('http://api.ocr.space/parse/image',
{ "apikey":"helloworld", "language":"eng", "isOverlayRequired":"false", "file": "asssets/img/test2.pdf" }, {})
.then(data => {
console.log("HTTP entered");
let result = JSON.parse(data.data); // data received by server
console.log(data.data);
})
.catch(error => {
console.log(error.error); // error message as string
});
And I'm guessing this because I'm able to send PDF files successfully via postman like below: my successful postman request
So - I'd love some help figuring out how to send this HTTP.post request successfully or convert the code I can get from postman to successful ionic-native syntax.
var form = new FormData();
form.append("apikey", "541496f13e88957");
form.append("language", "eng");
form.append("isOverlayRequired", "false");
form.append("file", "1page.pdf");
var settings = {
"async": true,
"crossDomain": true,
"url": "https://api.ocr.space/parse/image",
"method": "POST",
"headers": {
"cache-control": "no-cache",
"postman-token": "1aea47d5-a0eb-7768-5fa6-60c4cd76d453"
},
"processData": false,
"contentType": false,
"mimeType": "multipart/form-data",
"data": form
}
$.ajax(settings).done(function (response) {
console.log(response);
});
I appreciate any and all help!
I'm using cordova-plugin-file-transfer to send file instead of Base64Image or for Ionic 2 using ionic-native with the examples

HTTP.post to FCM Server not working

I am using Ionic 2 with HTTP native module to make a post request to FCM server for push notifications. The code I am using is:
HTTP.post(
"https://fcm.googleapis.com/fcm/send",
{
"notification": {
"title": "Notification title",
"body": "Notification body",
"sound": "default",
"click_action": "FCM_PLUGIN_ACTIVITY",
"icon": "fcm_push_icon"
},
"data": {
"hello": "This is a Firebase Cloud Messagin hbhj g Device Gr new v Message!",
},
"to": "device token",
},
{
Authorization: {
key: "AUTHORIZATION KEY HERE"
}
})
Its giving me an error:
Unimplemented console API: Unhandled Promise rejection:
Unimplemented console API: Error: Uncaught (in promise): [object Object]
I tried the post request with Postman, it works perfectly fine delivering push notifications.
The code with Postman is:
POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Content-Type: application/json
Authorization: key=Authorisation Key
Cache-Control: no-cache
Postman-Token: 446e253b-179a-d19b-21ea-82d9bb5d4e1c
{
"to": "Device Token",
"data": {
"hello": "This is a Firebase Cloud Messagin hbhj g Device Gr new v Message!",
}
"notification":{
"title":"Notification title",
"body":"Notification body",
"sound":"default",
"click_action":"FCM_PLUGIN_ACTIVITY",
"icon":"fcm_push_icon"
},
}
Questions:
I am unable to add content-type to the header in the HTTP post request, but it works with postman.
If I try to add a function(response) { to get the response from the server, it gives me an error. The documentation for the same is at https://github.com/wymsee/cordova-HTTP
why are you using HTTP native module? Angular has a built in Http.
Using this one (importing HttpModule from #angular/http in your NgModule) you can just call
import { Http, Headers } from '#angular/http';
......
constructor(public http: Http) { }
sendPushNotification(deviceId: string) {
let url = 'https://fcm.googleapis.com/fcm/send';
let body =
{
"notification": {
"title": "Notification title",
"body": "Notification body",
"sound": "default",
"click_action": "FCM_PLUGIN_ACTIVITY",
"icon": "fcm_push_icon"
},
"data": {
"hello": "This is a Firebase Cloud Messagin hbhj g Device Gr new v Message!",
},
"to": "device token"
};
let headers: Headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'key='+this.someKey
});
let options = new RequestOptions({ headers: headers });
console.log(JSON.stringify(headers));
this.http.post(url, body, headers).map(response => {
return response;
}).subscribe(data => {
//post doesn't fire if it doesn't get subscribed to
console.log(data);
});
}
push.on('notification', (data) => {
if (data.additionalData.foreground) {
// if application open, show popup
let confirmAlert = this.alertCtrl.create({
title: data.title,
message: data.message,
buttons: [{
text: 'Ignore',
role: 'cancel'
}, {
text: 'Go to',
handler: () => {
//TODO: Your logic here
this.navCtrl.setRoot(EventsPage, {message: data.message});
}
}]
});
confirmAlert.present();
} else {
//if user NOT using app and push notification comes
//TODO: Your logic on click of push notification directly
this.navCtrl.setRoot(EventsPage, {message: data.message});
}
});
push.on('error', (e) => {
alert(e);
});
});

Resources