Ajax Error callback not firing for iPhone - ios

Error callback does not work if async request is sent but success does! and it works perfectly fine in Android and browser.
In iPhone it works for synchronous request. here is my code.
other apis work perfectly fine.
$.ajax({
type: 'POST',
url: "https://api.cloud.appcelerator.com/v1/users/login.json?key=xxxxxxxxx",
data: {
"login": useremail,
"password": password
},
success: function (resp) {
console.log(resp);
console.log('User logged-in successfully');
},
error: function (e) {
console.log(e)
}
});
API returns status code 200 for correct email and password but 401 for incorrect one so if status code is 200 its works well I get response in success.

This seems to be a very common issue with Cordova + iOS + jQuery combo.
Seems like there are few ways to resolve this 401 error response handling issue. One is to add timeout time out attribute while making AJAX request and handling the error. The other approach is to handle it in the server side by sending request over HTTPS and returning back authentication token with error details in case of 401 error.
Request you to have a look at this post for more info.
Also currently you cannot differentiate these two errors (401 and 408 errors) in iOS as i could see this defect still open in official Apache Cordova Bug Tracking System.Request you to check out this bug

Related

Shopify API HTTP POST redirecting instead of POSTing

I have code (Classic ASP) which was recently working POSTing orders to Shopify but has now stopped POSTing and either creates an error "A Redirection problem has occurred" or redirects to the admin area of the Shopify site, depending on which XMLHTTP component I employ. The code below still works on older OS but not on Server 2016 where I am working.
I can't find much on Google but there was an indication in the Shopify Forum that the problem was a result of cookies (I have set none) and that this is overcome by sending a header containing X-Shopify-Access-Token:. I tried this using the "Authorize" setRequestHeader but it made no difference, or I got the syntax wrong or something. I used
xmlhttp.setRequestHeader "Authorization","X-Shopify-Access-Token=<token>"
Below is the code that worked a few weeks back. Variable jsondata contains valid JSON to send to create an order.
Set xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP.3.0")
xmlhttp.Open "POST", "https://<api key>:<passowrd>#<sitename>.myshopify.com/admin/orders.json", false, "<api key>", "<password>"
xmlhttp.setRequestHeader "Content-Type", "application/json; charset=utf-8"
xmlhttp.setRequestHeader "Content-Length", Len(jsondata)
xmlhttp.Send jsondata
Set xmlhttp = nothing
I expect a POST and a JSON order response but this is not happening - just a redirection to https://<sitename>.myshopify.com/admin. Any ideas anyone?

fetch() doing GET instead of POST on react-native (iOS)

I have the following code in my component:
fetch('https://domain.com/api', {
method: 'POST',
headers: {'Accept': 'application/json', 'Content-Type': 'application/json'},
body: JSON.stringify({
key: 'value'
})
}).
then((response) => {
console.log('Done', response);
});
And every time the request is a GET (checked server logs). I thought it was something to do with CORS (but apparently no such thing in react-native) and ATS (but already turned off by default, plus my domain is HTTPS). I've tried from a browser and from a curl and it worked perfectly, so a priori no issue on server configuration. Any idea what's going on here?
I'm using the latest react-native version.
After further digging, it was definitely an issue with the API + fetch. I was missing a slash at the end of the URL and the API issued a 301, that fetch didn't handle correctly. So I don't know if there is something to fix in the fetch function (and underlying mechanisms) but this fixed my issue :)
When a POST is redirected (in my case from http to https) it gets transformed into a GET. (Don't know why...)

Debug Angular's $http.jsonp(); on Safari iOS

I have this code on my Angular App controller:
$http.jsonp('http://192.168.1.210/json', config).success(function (data) {
vm.lightSensor = data.a0-vm.lightThreshold;
vm.detected = (data.d2==1) ? 'Yes' : 'No';
vm.toggle = (data.d7==1) ? 'on' : 'off';
vm.jsonerror = false;
}).error(function (data, status, headers, config) {
alert(status);
vm.jsonerror = true;
});
It throws a 404 status error when I do the alert, however, this happens on Safari iOS but not on iOS Chrome, where the request works fine.
I think, as the server is an Arduino, that it may be something to do with the request headers that Safari iOS is sending, that maybe the Arduino server doesn't like and returns a 404 error.
I tried to debug it with weinre, but it doesn't show any xhr requests (at least for me).
What other not-too-tedious ways are there to debug the request so I can see what headers are being sent considering that I don't have a Mac?
I already solved it. I could look at the headers by modifying the Arduino server to output the headers in the arduino serial console.
Turns out the problem was the arduino server itself, it didn't return a 200 code so it failed in Safari iOS. Somehow it still worked on the rest of the browsers, but I have no clue why.

firefox addon-sdk : handle http request timeout

I'm building a firefox add-on using the add-on sdk. I need to make a http request to a certain page and I want to handle the connection timeout but couldn't find anything in the api: https://addons.mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/request.html
What I'm actually looking is a callback in case the client couldn't connect to the server.
Is there a way to achieve this?
The SDK request will always call onComplete, when the request is considered done for the network. This means that onComplete is called in any case, disregarding if the request returned an error or a success.
In order to detect which error you've got, you need to check the Response object's (the object passed to the onComplete function) property "status" (response.status). It holds the status code for the request. To look up status codes, consider the list on the mozilla developer network. If the response status is 0, the request has failed completely and the user is probably offline, or the target couldn't be reached.
A timeout would either be a status code 504 or 0. The implementation would be similar to this:
var Request = require("sdk/request");
Request({
url: "http://foo.bar/request.target",
onComplete: function(response) {
if(response.status==0||response.status==504) {
// do connection timeout handling
}
// probably check for other status codes
else {
// assume the request went well
}
}
}).get();
I personally use a validation function on the request object, which returns me a number which depends whether I've got a correct response, an error from the web server or a connection issue (4xx and 0 status codes).

Crossdomain AJAX call to Luracast Restler API: "PUT" and "DELETE" sending "OPTIONS" - Why?

I've installed Luracast's Restler API framework and am having marvelous success with it all except when sending PUT or DELETE across domains. The below works fine when all on the same server, but when I cross domains, Firebug shows the the PUT or GET as OPTIONS, and it is not found on the server. Am baffled how to stop "OPTIONS" being sent instead of PUT or DELETE.
$.ajax({
url: url,
type: 'PUT',
data: "thename="+ $('#TheName').val(),
success: function(xhr, status) {
console.info(xhr);
},
error: function(xhr, status) {
console.info(xhr.responseText);
},
complete: function(xhr, status) {
$('#showResponse').val(xhr.responseText);
}
});
Per another thread somewhere, I've added the below to the Restler output:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, DELETE, PUT, OPTIONS');
You've got the right response headers, but you have to have your server respond to an OPTIONS request with those headers, too.
This is a cross-origin request, and is subject to something called preflighting. Before making the PUT or DELETE request the browser asks the target web server if it's safe to do so from a web page at another domain. It asks that using the OPTIONS method. Unless the target server says it's okay, the web browser will never make the PUT or DELETE request. It has to preflight the request, because once it's made the PUT or DELETE, it's too late to honor the response; sensitive information may have been leaked.
GET and POST are a bit more complicated, as sometimes the browser decides they are safe without asking first, while other times the browser will also do a preflight check. It depends on whether certain headers are used in the request.
The CORS spec has the gory details. The bottom line is that the code on your web page will not be allowed to make these requests unless the target web server supports the OPTIONS method, and the response to the OPTIONS method includes the headers saying that such requests are allowed.

Resources