I have tried POST request from dart code to django rest api on local machine.
the API works when I do POST from Postman but fails when using dart.
Can someone please explain why !
my dart code :
void post_call() async {
var headers = {
'Content-Type': 'application/json',
};
var data = {"_selectedValue":"yes","_DescriptionValue":"yes","_namefieldValue":"yes","_contactValue":"yes","_emailValue" : "yes"};
var url = Uri.parse('http://127.0.0.1:8000/first_app/forms/');
var res = await http.post(url, headers: headers, body: json.encode(data));
if (res.statusCode != 200) throw Exception('http.post error: statusCode= ${res.statusCode}');
print(res);
}
the API works when I do POST from Postman but fails when using dart.
Related
i have this URL
https://zozor54-whois-lookup-v1.p.rapidapi.com/?rapidapi-key=MYAPIKEYb&domain=DOMAINTOCHECK&format=FORMATTYPE
rapid API gives two header's and other things
I Tried This Code By Exploring HTTP package But Not Working:
import 'package:http/http.dart' as http;
void main() async {
var url = 'https://zozor54-whois-lookup-v1.p.rapidapi.com/?domain=sendrank.com&format=json';
var headers = {
'X-Rapidapi-Key': APIKEyY
'X-Rapidapi-Host': 'zozor54-whois-lookup-v1.p.rapidapi.com',
'Host': 'zozor54-whois-lookup-v1.p.rapidapi.com'
};
var response = await http.get(url, headers: headers);
print(response.body);
}
You need to encode the url with the parameters
final queryParameters = {
'domain': 'sendrank.com',
'format': 'json',
};
final uri = Uri.https('zozor54-whois-lookup-v1.p.rapidapi.com', '/', queryParameters);
final response = await http.get(uri, headers: {
'X-Rapidapi-Key': APIKEyY
'X-Rapidapi-Host': 'zozor54-whois-lookup-v1.p.rapidapi.com',
'Host': 'zozor54-whois-lookup-v1.p.rapidapi.com'
});
See How do you add query parameters to a Dart http request?
I am working with Rad Studio (Delphi) and I am trying to connect to a RapidApi Endpoint via a Rest Component of Rad Studio.
Although I use the "x-rapidapi-key" & "x-rapidapi-host" as parameters on the Rest Component, I get a 401 unauthorized Response.
Any Ideas?
Thank you
It's unclear but probably you need to pass x-rapidapi-host and x-rapidapi-key as the request headers, not parameters.
For example, try something like this
var axios = require("axios").default;
var options = {
method: 'GET',
url: 'https://example.p.rapidapi.com/',
params: {query: 'something here'},
headers: {
'x-rapidapi-host': 'example.p.rapidapi.com',
'x-rapidapi-key': '12345'
}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
I am making POST request using http lib in Dart. After I wandering around former answers with no luck. Even official doc
import 'package:http/http.dart' as http;
Future<http.Response> createAlbum(String nameEN) {
return http.post(
'http://localhost:8000/api/products/',
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'nameEN': nameEN,
}),
);
}
And I test with unittest like this
testWidgets('POST request from offcial docs', (WidgetTester tester) async{
final http.Response res = await createAlbum("Jordan");
print(res.statusCode);
});
Attempt:
PostmanApp can make request and get 201 in response. However, when I copy&paste the Dart code from it and test it does not work
I always get 400 and no request comes to localhost:8000
testWidgets('POST request from postman', (WidgetTester tester) async{
var headers = {
'Content-Type': 'application/json'
};
var request = http.Request('POST', Uri.parse('localhost:8000/api/products/'));
request.body = '''{\n "name_jp": "李天宝",\n "name_en": "Sarit",\n "description": "Developer",\n "qty": 3,\n "expiry": "2099-12-25",\n "barcode": "549XXXYYYYYY",\n "price": "{\\"bounds\\": \\"[)\\", \\"lower\\": \\"12\\", \\"upper\\": \\"6\\"}",\n "medium_price": 60\n}''';
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(200);
print(await response.stream.bytesToString());
}
else {
print(response.statusCode);
print(response.reasonPhrase);
}
});
Problem
Dart response returned to me is 400 and on the server side request has not been sent out to my http://localhost:8000/api/products/
Question:
What is the correct POST syntax?
References:
HTTP POST with Json on Body - Flutter/Dart
Bad state: Cannot set the body fields of a Request with content-type "application/json"
Flutter FormatException: Unexpected character (at character 1)
Http POST request with json content-type in dart:io
You have non-ASCII characters. Did you set the proper ; charset=UTF-8 in your Content-Type header? Or even better, JSON doesn't understand non-ASCII unless you \u encode them.
Lesson learnt here
Add CORS enable in chrome
flutter run -d web. Do not use -d chrome
Make request from cors enabled chrome by clicking. Do not use unittest!
I have created a post request in aqueduct dart and it takes json as body parameter, and I need to send that request body to thirdparty api , upon getting response from third party api I need to return that response to user. I have updated the code and printed the response header and it says http 400 (bad request)
here is the code :
#override
Controller get entryPoint {
String dataRecieved;
var completer = new Completer();
var contents = new StringBuffer();
final router = Router();
// Prefer to use `link` instead of `linkFunction`.
// See: https://aqueduct.io/docs/http/request_controller/
router.route("/uploadurl").linkFunction((request) async {
final req = await request.body.decode();
// print( await request.body.decode());
HttpClient client = new HttpClient();
client.badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
var auth = 'Bearer ' +
'eyJ...';
await client
.postUrl(Uri.parse(
'https://<removed>/api/datalake/v3/generateDownloadObjectUrls'))
.then((HttpClientRequest requestSend) {
requestSend.headers
.add("Content-Type", "application/json; charset=UTF-8");
requestSend.headers.add("Authorization", auth);
// requestSend.headers.contentLength = request.body.length;
print(req);
requestSend.write(req);
return requestSend.close();
}).then((HttpClientResponse response) async {
print(await response.contentLength);
var resStream = response.transform(Utf8Decoder());
await for (var data in resStream) {
print('Received data: $data');
}
print(await response.statusCode);
}).catchError((e) {
print("Request error: $e"); // The only case
});
print(contents);
return Response.ok({"key": dataRecieved});
});
return router;
}
when I make a request from the postman , I get
{
"key": null
}
I think I am not able to send the correct request to third party API , because when I tested third party API from the postman, it was sending correct response
My pubspec.yaml file is :
name: proxydl
description: An empty Aqueduct application.
version: 0.0.1
author: stable|kernel <jobs#stablekernel.com>
environment:
sdk: ">=2.0.0 <3.0.0"
dependencies:
aqueduct: ^3.0.0
http: ^0.12.0+2
dev_dependencies:
test: ^1.0.0
aqueduct_test: ^1.0.0
This is what I am sending from postman as post request:
{
"paths": [
{
"path": "/f1/f2.log"
}
]
}
This is my first POC with Dart on the server side.
Upon further investigation I found the answer:
final req = await request.body.decode();
var envalue = json.encode(req);
For now, this worked, but I feel there might be a better answer for this
I am trying to get data from API. I need to pass value from the body, in postman without a header: application/JSON data is not displayed.
final response = await http.post(
"http://192.168.10.25:8080/Login/validateusername",
body: {"username": "user#PYA"},
headers: {'Content-Type': 'application/json'},
);
Error Message:
E/flutter (28851): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter (28851): Bad state: Cannot set the body fields of a Request with content-type "application/json".
Add the content type application/json
Future<String> apiRequest(String url, Map jsonMap) async {
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
// todo - you should check the response.statusCode
String reply = await response.transform(utf8.decoder).join();
httpClient.close();
return reply;
}
Simply encode body to json object when using content-type "application/json"
http.Response response = await http.post( uri , headers: headers, body: JsonEncoder().convert(body));
Another simple way is as bellow
import 'package:http/http.dart' as http;
String body = json.encode({
'foo': 'bar',
'complex_foo' : {
'name' : 'test'
}
});
http.Response response = await http.post(
url: 'https://example.com',
headers: {"Content-Type": "application/json"},
body: body,
);
use the http dart package
var data = {username:"username",password:"password"};
http.Response response = await http.post(
"yourApiroute",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: {"username": data.phone, "password": data.password});
var json = jsonCodec.encode(data);
print("json=$json");
var url = "http:yourAPIrouter.com/etc";
var response = await http.post(
url,
headers:{ "Accept": "application/json" } ,
body: { "json": '$json'},
encoding: Encoding.getByName("utf-8")
);
and dont forget add the key "json" in postman
I am doing almost the same. However, I tried to avoid doing back-end, like in your case. I just did a minimal php request so that I would not waste or patience learning what is needed to develop a user management controller.
However, I faced several limitations and problems that Flutter alone can't solve. After some denial, I gave a try. Lumen, a light version of the Laravel Framework, some tutorials and some past experience, I eventually realized that the API should carry most of the authentication, and not the application itself. I digressed.
In my case, the code of the fuction to a http post is:
Future<Post> createPost() async {
final url = "http://localhost:8000/api/login";
Map<String, String> body = {
'user': user.text,
'pass': pass.text,
};
await http.post(url, body: body);
print(body);
return http.;
}
I first convert it into a map. I prefer this method over parsing json, because down the line, if I need to add more variables, I just make the map bigger.
I just have a question: What does your http://192.168.10.25:8080/Login/validateusername look like? I think that there is no need to specify the type of information that your body parses.