jQuery.GET intermittent failure in Safari in ipad - javascript

I have the following utility function which I use as a standard way of adding headers to an HTTP GET request.
const get1 = function(url, callback) {
console.log("in get1 with url : " + url);
return new Promise(function(resolve, reject) {
firebase.auth().currentUser.getIdToken()
.then(function(idToken) {
return {
'Authorization': 'Bearer ' + idToken,
'ACTING_ON_BEHALF_OF': ns.actingAs
};
})
.then(function(headers) {
resolve($.get({
url: url,
headers: headers,
dataType: "json",
error: function(jqXHR, textStatus, errorThrown) {
alert(textStatus);
alert(errorThrown);
alert(jqXHR.responseText);
}
}));
});
});
};
I call it with structures similar to this
const targetUrl = ns.operation + "/" + ns.stage + "/" + ns.category;
utils.get1("/api/gameconfig/v1/oddoneout/" + targetUrl)
.then(function(data) {
console.log("THEN Block")
// blah blah blah
});
This seems to work reliably in all browsers except Safari on iPad where, periodically, the GET request appears to be executed but the .then block never gets entered.
Debugging the javascript seems to indicate that the HTTP request is still executing, but the server side seems to think that it has successfully completed the request and returned a response.
I'm at a loss as to why I see this behaviour. There doesn't seem any pattern to it. Sometimes I can make 50 calls without a problem, sometimes it fails more or less immediately.
Any help will be gratefully received - even if it's hints about how to debug this.
I'm using jQuery 3.3.1 if that makes any difference.

Related

Error in HTTP GET Request with gadgets.io.makeRequest

Sorry but I spent a half a day practicing first with gadgets.io.makeRequest, and can not understand why the request response contains an error. The code is Javascript working as OpenSocial gadget:
requestURI = "https://jazz.server.com:9443/rm/views?projectURL=https%3A%2F%2Fjazz.server.com%3A9443%2Frm%2Fprocess%2Fproject-areas%2F_FvrWIG3nEeexYJvvGxVsZg&oslc.query=true&oslc.prefix=rt=<https://jazz.server.com:9443/rm/types/>&oslc.select=rt:_W0SGoW3nEeexYJvvGxVsZg";
makeGETRequest(requestURI);
...
function makeGETRequest(url) {
try {
var params = {};
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
params[gadgets.io.RequestParameters.HEADERS] = {
"Accept" : "application/rdf+xml",
"OSLC-Core-Version": "2.0"
}
gadgets.io.makeRequest(url, function(obj) {
console.log("===== HTTP REQUEST START =====");
console.log("Method : GET");
console.log("URL : " + url);
console.log("Response : " + obj.text);
console.log("====== HTTP REQUEST END ======");
}, params);
}
catch(err) {
console.log("Can not perform HTTP request because of error: " + err.message);
}
};
When I do the same request with REST Client in Firefox, everything works properly. But if I do that with the code above, then I get an error in the log (abbreviated):
===== HTTP REQUEST START =====
common.js:311 Method : GET
common.js:312 URL : https://jazz.server.com:9443/rm/views?projectURL=https%3A%2F%2Fjazz.server.…roject-areas%2F_FvrWIG3nEeexYJvvGxVsZg&oslc.query=true&oslc.prefix=rt=<https://jazz.server.com:9443/rm/types/>&oslc.select=rt:_W0SGoW3nEeexYJvvGxVsZg
common.js:313 Response : {"errorMessage":"Illegal character in query at index 178: https://jazz.server.com:9443/rm/views?projectURL=https%3A%2F%2Fjazz.server.com%3A9443%2Frm%2Fprocess%2Fproject-areas%2F_FvrWIG3nEeexYJvvGxVsZg&amp;oslc.query=true&oslc.prefix=rt=<https://jazz.server.com:9443/rm/types/>&oslc.select=rt:_W0SGoW3nEeexYJvvGxVsZg","errorClass":"java.lang.IllegalArgumentException","errorTrace":["java.net.URI.create(URI.java:871)","org.apache.http.client.methods.HttpGet.<init>
...
common.js:314 ====== HTTP REQUEST END ======
I tried to replace greater and less symbols by their hex values but there's no result. And there's no ideas currently.
May be somebody could make a fresh sight to the code and define the problem on the fly. Help me please, I'm at a dead end.
Thank you very much in advance for any advice!
The error in your Response indicates the Java system on the server side can't create a valid URI from your query. Therefor it throws back an error
My best guess would be the dot just before query=true in oslc.query=true. And therefor all following uses of oslcDOT .
From RFC 1738 specification:
Thus, only alphanumerics, the special characters "$-_.+!*'(),", and reserved characters used for their reserved purposes may be used unencoded within a URL.
I discovered that gadgets.io.makeRequest isn't very stable as I would like to expect. May be I do some wrong but sometimes this function completes without any feedback and without starting the response function in the parameters. I changed to next code:
function makeGETRequest(urlValue) {
try {
$.ajax({
url: urlValue,
type: 'GET',
dataType: 'text',
headers: {
'Accept': 'application/rdf+xml',
'OSLC-Core-Version': '2.0'
},
success: function (result) {
var data = result;
},
error: function (error) {
console.log("Can not perform HTTP request because of error: " + error.message);
}
});
}
catch(err) {
console.log("Can not perform HTTP request because of error: " + err.message);
}
};
And there's no problem!

Call Sharepoint APIs from localhost

This thread is very similar to that question but I am not convinced by the answer given ("The library can't be used if the application is not deployed on the same sharepoint site domain") because in this page here the author insists on the fact that it is possible via the object SP.RequestExecutor(appweburl).
So I followed all the steps mentionned in the page and I ended up with this code:
$(document).ready(function () {
var hostweburl = decodeURIComponent("https://lpl.sharepoint.com/sites/TestPortail");
var appweburl = decodeURIComponent("http://localhost");
var scriptbase = hostweburl + "/_layouts/15/";
// Load the .js file using jQuery's getScript function.
$.getScript( hostweburl + "/_layouts/15/SP.RequestExecutor.js", continueExecution );
function continueExecution() {
var executor;
// Initialize your RequestExecutor object.
executor = new SP.RequestExecutor(appweburl);
console.log(executor); // just to see if created
// You can issue requests here using the executeAsync method
// of the RequestExecutor object.
executor.executeAsync({
url: appweburl + "/_api/SP.AppContextSite(#target)/web/title?#target='" + hostweburl + "'",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
console.log('Successfully obtained data.');
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('There is an error.');
console.log(jqXHR.status);
console.log(textStatus);
console.log(errorThrown);
}
});
}
});
When I executed it from localhost I get this:
I have been looking for the solution for 2 days. Maybe it is because the localhost is not a https, but even with this great answer I have not managed to do it (wamp won't start).
Any help would be appreciated.

.done not fired on ajax call

I have a function that makes a ajax call. The .done doesn't seems to be firing. I checked for the error on my console. It says
function getIncidentInfo() {
$.ajax({
type: "GET",
url: "../../page_components/statsboard/stats.php",
data: $(this).serialize(),
dataType: "json",
}).done(function(response) {
incidentAr = response;
for (var i in incidentAr) {
var zaNorth = parseInt(incidentAr[i].zaNorth);
......
}
}).fail(function(xhr, status, error) {
console.log("Status: " + status + " Error: " + error);
console.log(xhr);
});
}
I asked my friend to try the same piece of code and it works.
The script in stats.php is throwing an XDebug error and is returning HTML describing the error instead of the JSON you are expecting. Loading the stats.php page in a browser, or check your PHP logs to find out what the error is.
Check .always(response) instead of .done(response). Some services return non 200 codes with a response body to describe the error.
Check response.responseJSON, response.responseText, and response.responseXML. You may have to state response.responseJSON = eval(respaonse.responseText).
However, I see that the responseText is of HTML type, so my guess (and I say this because you're getting a 200 status and not a 404 or 500) is that you are getting a more generic server error that is rendering a response from a route you did not intend to query.

How to have NanoHTTPD respond to AJAX

I'm attempting to get NanoHTTPD (on an android device) to respond to AJAX requests in a way that the requesting javascript can interpret the response.
I've implemented the NanoHTTPD serve method:
public NanoHTTPD.Response serve(String uri, NanoHTTPD.Method method,
Map<String, String> header,
Map<String, String> parameters,
Map<String, String> files) {
String msg = "Hello, you have connected.";
return newFixedLengthResponse( msg );
}
And if I connect from the local webbrowser to "http://127.0.0.1:8080" it loads a page with the source:
<html>
<head></head>
<body>Hello, you have connected.</body>
</html>
So far so good, although I'm not sure where the html formatting is introduced.
But what I am stuck on is if I use AJAX from javascript to try to pass data:
$.ajax({
url: 'http://127.0.0.1:8080',
type: 'POST',
data:{ printData: dataToPrint },
success: function(d){
alert('success');
},
error: function (jqXHR, textStatus) {
alert("failed, jqXHR: " + jqXHR.responseText + " " + jQuery.parseJSON(jqXHR.responseText) + " textStatus: " + textStatus);
}
})
(This is just one example, I've tried success/fail/done/error methods, I've tried specifying the datatype, I've tried different parameters in the return functions, none of it works). When this javascript is run the NanoHTTPD server receives the printData just fine, but when it sends it response it is only ever the error/fail method that is triggered and the method parameters never contain anything - I cannot set the status or the return message or anything.
I've tried different returns from the Serve method including:
String mime_type = NanoHTTPD.MIME_PLAINTEXT;
String msg = "{\"status\":\"1\",\"responseText\":\"this is the response\"}";
InputStream testReply = new ByteArrayInputStream(msg.getBytes(StandardCharsets.UTF_8));
// return newFixedLengthResponse(NanoHTTPD.Response.Status.OK, "", msg);
// return new NanoHTTPD.Response( NanoHTTPD.Response.Status.OK, mime_type, testReply);
// return NanoHTTPD.newFixedLengthResponse( NanoHTTPD.Response.Status.OK, mime_type, msg);
// return NanoHTTPD.newFixedLengthResponse(msg);
None of these work.
I also tried this javascript:
$.get("http://127.0.0.1:8080", function( my_var ) {
console.log(my_var);
});
If this is run my breakpoint on NanoHTTPD is triggered, but the javascript method is not triggered at all.
I think you need to add these headers in your server response:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 86400

How to detect if browser supports PUT/DELETE verbs? [duplicate]

Is there a way to see if a client browser supports PUT or SEARCH methods for usage with JQuery & AJAX requests?
HTML5 PUT/DELETE methods not working in Chrome?
Are the PUT, DELETE, HEAD, etc methods available in most web browsers?
I have the following code, and PUT does not appear on the server side for me in Chromium and Chrome ... I'd like to know, if PUT isn't supported by the browser, how to change it to a POST request ... for backwards compatibility
function do_data(url, action, query) {
try {
if ($.browser.msie) {
var xdr = new XDomainRequest();
if (query !== null) {
console.log(query);
xdr.open(action, url + '?' + $.param(query));
} else {
xdr.open(action, url);
}
xdr.onload = function() {
var data = $.parseJSON(this.responseText);
show_data(data);
};
xdr.send();
} else {
if (query !== null) {
$.ajax({
url: url,
data: query,
type: action,
success: function(data) {
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
}
});
} else {
console.log(query);
$.ajax({
url: url,
type: action,
success: function(msg) {
console.log(data);
}
});
}
}
} catch (e) {}
}
Using the above code, if I use "PUT" on Chromium / Chrome, error: function(jqXHR, textStatus, errorThrown) will print out simply error.
On the server side, I see the REQUEST_METHOD: OPTIONS and not PUT.
Just to confirm, for anyone who comes across this ... there isn't a programmatic way
The common way of handling the lack of PUT and DELETE support in most browsers is to use HTTP POST tunneling. Basically you use a POST and add the real VERB to a X-HTTP-Method-Override HTTP header. On the service you check for the latter, if not found use the normal HTTP method.
See here for more info.

Categories