I've a Ionic v3 application, and when I build it on a android device, all the Http GET request work, but when a POST request is launch, I've got a CORS error...
That's my request:
//Headers
let headers = new HttpHeaders();
headers = headers.append('Content-Type', 'application/json');
//Post data
let post_data = {
my_body: blabla
};
this.http.post(ENV.API_URL + 'test/test', post_data, {headers: headers}).subscribe((data: any) => {
})
If anyone can help me?
Related
In my Xamarin Forms app I have a very basic GET request that results in a 504 'Method not allowed' on Android.
This is the controller that I am calling:
[AllowAnonymous]
[HttpGet]
[Route("api/system/backendversion")]
public int GetBackendVersion()
{
return 20200924;
}
This is the code that performs the request
var _client = new HttpClient();
var content = new StringContent(json, Encoding.UTF8, "application/json");
var httpRequest = new HttpRequestMessage(httpMethod, url)
{
Content = content,
Version = HttpVersion.Version10
};
var response = await _client.SendAsync(httpRequest);
The problem disappears when I change the HttpClient implementation from "Android" to "Managed".
Also the webrequest works fine in the XF.UWP version of my app.
I believe I put it on Android for a reason, but I'm unsure what the reason was (probably speed). I'm curious what goes wrong here.
Apperantly it breaks because the content (header?) is set to json when there is no json.
I fixed it like this:
var httpRequest = new HttpRequestMessage(httpMethod, url)
{
Version = HttpVersion.Version10
};
if (!string.IsNullOrWhiteSpace(json))
{
httpRequest.Content = new StringContent(json, Encoding.UTF8, "application/json");
}
var response = await _client.SendAsync(httpRequest);
this error is similar to iOS where you get an error if you put json body in a get request
if (httpMethod == HttpMethod.Get && !string.IsNullOrWhiteSpace(json))
{
Debugger.Break();//a get request with a body is not allowed on iOS and results in a error https://stackoverflow.com/questions/56955595/1103-error-domain-nsurlerrordomain-code-1103-resource-exceeds-maximum-size-i
}
I'm trying to receive the response on a http post but the response comes empty. I know its something basic but i can't make it work.
It should receive a JSON with some data, but the data doesn't come, probably its a problem on the reply part on my code.
Heres the code:
Future<void> _login2() async {
HttpClient client = new HttpClient();
client.badCertificateCallback =
((X509Certificate cert, String host, int port) => true);
String url = 'https://sistema.hutransportes.com.br/api/login.php';
Map map = {"user": "test", "pass": "123456"};
HttpClientRequest request = await client.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(map)));
HttpClientResponse response = await request.close();
String reply = await response.transform(utf8.decoder).join();
print(reply); //should show the data from the http
}
I would recommend you to use the powerful library https://pub.dev/packages/dio
i am trying to sign a http request to aws api gateway in android using okhttp. i have more or less used the code in this stackoverflow question stackoverflow question
i use CognitoCachingCredentialsProvider() to get a credentialsProvider object. i then use getCredentials() to get the credentials. i then use the following: credentials.getAWSAccessKeyId(), credentials.getAWSSecretKey() and credentials.getSessionToken() to get the necessary keys and token. i use them in postman and am able to successfully execute the api gateway.
the request fails in android using okhttp, returning a code 403 with the message "Missing Authentication Token".
this is how i prepare the request: i build a DefaultRequest object, setting the endpoint and httpmethod. i then use AWS4Signer to sign the request, passing the credentials object as the signer.sign(defaultRequest, credentials) parameter.
i get a map of headers by calling getHeaders() on the defaultRequest. i create two lists, one called key for the key and one called value for the value. i then loop through the map, loading the keys and corresponding values into the two lists.
i then build my okhttp request as follows:
Request request = new Request.Builder()
.url(my ApiEndPoint)
.addHeader(key.get(0), value.get(0))
.addHeader(key.get(1), value.get(1))
.addHeader(key.get(2), value.get(2))
.addHeader(key.get(3), value.get(3))
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.post(body)
.build();
i notice the following:
in the headers map, key x-amz-security-token has a value ....ending in hKADF87VZ44w9IvZ1gU=
printing out the okhttp request, the key x-amz-security-token has a value .... ending in hKADF87VZ44w9IvZ1gU\u003d
the = is replaced by \u003d, could this be the problem? if so, how to prevent this?
otherwise, any help in solving this problem will be greatly appreciated.
thanks
managed to solve the problem. seems that assigning the headers to the OkHttp request was the problem. so here's my code:
i first get AWSSessionCredentials credentials. then:
AmazonWebServiceRequest amazonWebServiceRequest = new AmazonWebServiceRequest() {
};
String API_GATEWAY_SERVICE_NAME = "execute-api";
com.amazonaws.Request requestAws = new DefaultRequest(amazonWebServiceRequest, API_GATEWAY_SERVICE_NAME);
you can use either the service endpoint:
URI uri = URI.create("https://apigateway.eu-west-1.amazonaws.com");
or your api url (the invoke url for api as per Api Gateway console Stages option (The deployed api)):
String invokeUrl = "https://xxxx.execute-api.eu-west-1.amazonaws.com/yyy/zzzzz";
// using the invoke url
URI uri = URI.create(invokeUrl);
requestAws.setEndpoint(uri);
requestAws.setResourcePath(invokeUrl);
requestAws.setHttpMethod(HttpMethodName.POST);
now sign the request
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(API_GATEWAY_SERVICE_NAME);
signer.setRegionName(Region.getRegion(Regions.EU_WEST_1).getName());
signer.sign(requestAws, credentials);
get the headers
// get map of headers
Map<String, String> headers = requestAws.getHeaders();
// create objects for the headers to add manually in OkHttp request builder
String x_date = null;
String x_token = null;
String authorization = null;
//get and assign values
for (Map.Entry<String, String> entry : headers.entrySet()) {
if (entry.getKey().equals("x-amz-security-token")) {
x_token = entry.getValue();
}
if (entry.getKey().equals("X-Amz-Date")) {
x_date = entry.getValue();
}
if (entry.getKey().equals("Authorization")) {
authorization = entry.getValue();
}
}
build the OkHttp request:
Request request = new Request.Builder()
.url(invokeUrl)
.addHeader("Content-Type", "application/json")
.addHeader("X-Amz-Date", x_date)
.addHeader("x-amz-security-token", x_token)
.addHeader("Authorization", authorization)
.post(body)
.build();
now make your OkHttp call.
hope this is helpful to someone.
Getting connected from an Android app to Toodledo API v3 works.
So, I know that I have a valid access_token (and refresh token).
GET requests work.
How can I add a folder ... using a POST request?
The code is below ... it keeps on spinning for new access tokens.
HttpResponse response = null;
JSONObject folderJS;
try {
Credential cred = flow.loadCredential( userId);
String apiCallUrl = "https://api.toodledo.com/3/folders/add.php";
GenericData data = new GenericData();
data.put( "name", folderName);
data.put( "private", "1");
// data.put( "access_token", accessToken); <== this is wrong
JsonHttpContent httpContent = new JsonHttpContent(new JacksonFactory(), data);
response = HTTP_TRANSPORT.createRequestFactory( cred).buildPostRequest(
new GenericUrl( apiCallUrl), httpContent).execute();
The problem was:
data.put( "access_token", accessToken);
When you add this line you get errors in processing the request. So, user error.
I try the following request in Titanium
var xhr = Titanium.Network.createHTTPClient();
xhr.open("POST", "http://www.example.com");
var params = {
username = "username",
password = "password"
};
xhr.send(params);
The problem is that it works in iPhone Simulator, but not on the android emulator/device
The request comes through to the server, but if I print the params in my php page, they are both empty.
Some webservers need the content type set or they don't pull out the parameters. Have you tried sniffing the header and contents of the Android traffic through proxy server?
var xhr = Titanium.Network.createHTTPClient();
xhr.open("POST", "http://www.example.com");
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var params = {
username = "username",
password = "password"
};
xhr.send(params);
This works for me I'm using Lift. Maybe your server doesn't handle it well.