Originally I use setRequestHeader() in kendo UI datasource's beforeSend event to set the bear token in the http header and it works great.
Now, in order to handle the token timeout issue, I would like to refresh the token in beforeSend event. But because Fetch is an async function so the event beforeSend will return immediately so the kendo datasource used the old token and then got 401 finally.
I checked that beforeSend doesn't support async so any idea could achieve this purpose?
Updated
As recommended I used ajaxSend() which will be called everytime a ajax call is invoked.
Inside ajaxSend(), I use fetch (cross domain) to refresh the token so that the next ajax call will use a new token in the request header:
$(document).ajaxSend(function (e, xhr, options) {
console.log('Event: ', e);
console.log('xhr: ', xhr);
console.log('Options: ', options);
console.log('Old access_token: ', my_user.access_token);
let formData = 'grant_type=refresh_token&refresh_token=' + my_user.refresh_token;
fetch('url/Token', { //---cross domain server
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded'},
body: formData })
.then(data => data.json())
.then(user => {
if (user.access_token) {
xhr.setRequestHeader('Authorization', 'Bearer ' + user.access_token);
console.log('New access_token: ', user.access_token);
}
else {
console.error('error');
}
}).catch(error => {
console.error(error.message);
})
});
But strangely, don't know why the coming ajax call still used 'Old access_token' rather than 'New access_token'.
2nd Update
I found out ajaxSend doesn't support async either.
There is another post has the same question with mine. jQuery: how to make ajaxSend wait for another Ajax response before proceeding?
The answer in that post suggested that instead of making the original ajax request to wait, another approach is to abort the original request and retry the request after the async call (mine is fetch) completed.
I have such idea before but it doesn't suit for my case because I am using Kendo UI grid to wait for the response then the grid will be auto updated. If I abort the original request and retry it, the Kendo UI grid won't be updated automatically because the request was aborted. Unless I update the Kendo grid by code manually but it's not my intention.
You can try to intercept requests with ajaxSend.
$(document).ajaxSend(function (e, xhr, options) {
console.log('Event: ', e);
console.log('xhr: ', xhr);
console.log('Options: ', options);
xhr.setRequestHeader('Authorization', 'Bearer ' + 'jwt');
});
This will intercept every request. I tested it with read and fetch dataSource methods.
.ajaxSend()
Note: As of jQuery version 1.8, this method should only be attached to document.
Related
If I put the parameters in, I get no success/error/completed callbacks, but Fiddler shows a 200 response and my requested json data is there. That's the key. Fiddler is showing the round trip was a success and the requested data is here client side and in good order. Problem is backbone success/failure/completed not called. Just get a big nothing.
With the exact same base URL, if I take the parameters out (and remove them from my web service in parallel), both success and completed are triggered. Below is my fetch "with" parameters:
myModel.fetch({
data: {
name: 'Bob',
userid: '1',
usertype: 'new'
}
}, {
success: (function () {
alert(' Service request success: ');
}),
error: (function (e) {
alert(' Service request failure: ' + e);
}),
complete: (function (e) {
alert(' Service request completed ');
})
});
How can the backbone behavior be different? It's the same URL, just with or without parameters.
I'm guessing the distinction is that under the hood in the backbone fetch, the "with" parameters scenario is a post and the "without" parameters is a simple get. The IE console reflects this with slightly different output.
"With" parameters my IE browser console reports a warning (not an error but a warning) that the request required CORS:
!SEC7118: XMLHttpRequest for http://example.com/service/myservice.asmx/myoperation?name=Bob&userid=1&usertype=new required Cross Origin Resource Sharing (CORS).
I think it's just telling me "hey, you made a cross origin request and I let it through". "Without" the parameters I don't get that warning. I do have the service headers set to:
Access-Control-Allow-Origin: *
And the responses do indeed come back reflecting that policy.
So the question is why don't the backbone success/error/completed callbacks trigger "with" the parameters? The data makes it back. Shouldn't backbone reflect success?
Put your success, error, and complete methods in the same object you have data. There should only be the single object. Under the hood Backbone simply uses jQuery's ajax() method so the object you pass to fetch() can use any property that could be included in the settings object passed to $.ajax().
myModel.fetch({
data: {
name: 'Bob',
userid: '1',
usertype: 'new'
},
success: (function () {
alert(' Service request success: ');
}),
error: (function (e) {
alert(' Service request failure: ' + e);
}),
complete: (function (e) {
alert(' Service request completed ');
})
});
I would like to use Ajax to perform an action in OFBiz without the page refreshing. The task will be like filters. When I choose any Checkbox it should perform some action and display the result in the very same page.
What are all the steps i need to do?
I would appreciate some sample code for controller.xml,javascript calling Ajax ..etc
Thanks.
You can use form submission through ajax on an event in your ftl's. Here's a sample code for ajax call from say an ExampleCreateParty.ftl:
$.ajax({
url: '<#ofbizUrl>addSecurityPermissionToSecurityGroup</#ofbizUrl>',
type: 'POST',
accepts: 'xml',
data: $("form#Permissions").serialize(),
success: function(e) { console.log(e);
var xmlDoc;
try {
xmlDoc = $.parseXML(e);
var error = $(xmlDoc).find("Message").find("Error").find("ErrorCode").text();
var errorMsg = $(xmlDoc).find("Message").find("Error").find("ErrorMessage").text();
if (error=='0'){alert(errorMsg);}
console.log(xmlDoc);
} catch (err) {
alert('Saved Successfully!');
}
},
error: function(e) { console.log(e); }
})
Here in response to the service called i.e. addSecurityPermissionToSecurityGroup you can specify the response in the controller.xml which you can get within the success key in the ajax call itself.
To see a full end-to-end example have a look at this OFBiz page
As you can see whenever you change the product configuration, the product price is updated with Ajax call. Then you can find out for yourself the freemarker file containing javascript and the controller doing calculations and returning it back.
I'm doing a jsonp call in my mobile app at startup to connect to my server. I'm using Phonegap 2.1 and Zepto 1.0-rc1. At the bottom of my html page, I do the init stuff on DOM ready.
<script type="text/javascript">
if (!$) {$ = Zepto};
$(init);
document.addEventListener('deviceready', Perksea.deviceReady);
</script>
...
function init() {
var router = new Backbone.Router();
...
}
function deviceReady() {
isConnected();
isConnected();
}
function isConnected() {
$.ajaxJSONP({
url: 'http://localhost/isconnected',
success: function(response) {
console.log('response is ' + response);
}
});
}
The first JSONP call will print "response is undefined" but the second JSONP call works. I've even tried putting the JSONP call in a setTimeout(isConnected, 5000) with the same result. Have already checked that the url is correct etc.
Has anyone seen something like this?
Thanks
Steve
since you are getting into the "success" callback function on the first call (where response is undefined), are you sure that your server is properly responding to the first call? Sounds like it is returning a 200 response, but with no data for that first call.
You can try adding an 'error' callback to see if that provides anything useful as well
$.ajaxJSONP({
url: 'http://localhost/isconnected',
success: function(response) {
console.log('response is ' + response);
}
error: function(response) {
console.log('error is ' + response);
}
});
Finally, because AJAX is Asynchronous, your 2 calls to isConnected() are going to fire one immediately after the other, not waiting for the first to respond. I'm curious what it looks like on the server side (see above).
It is working right now , but I have some feedback of user saying that the facebook popup is blocked by the browser
So what I am doing right now: I have a form that is being validated via ajax (making a call to a php page) , then if the response is successful, it ask for the user login/permissions. I assume that the popup is sometime blocked because the browser consider the ajax response not as an user action.
So my code looks like this :
$("#submit").click(function (event) {
event.preventDefault();
$.ajax({
url: url,
type: type,
data: form_data,
success: function(result){
if(result==""){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
FB.api('/me/permissions', function (response) { ... });
} else if (response.status === 'not_authorized') {
FB.login(function (response) { ... });
}
}
}
}
});
Any idea other than putting the facebook calls before the form validation?
You can make ajax request as synchronous call. I don't like it though
btw, what kind of validation you are doing?
I'm using jQuery 1.4.2 and am trying to perform a simple AJAX request. The target URL returns a JSON string (I validated it with jslint). The request works in Firefox and Chrome, but doesn't want to work in IE8, and I can't determine why. Here is the call:
jQuery.ajax({
url: 'http://' + domain + '/' + 'helper/echo/',
dataType: 'json',
success: function(data) {
alert(data);
},
beforeSend: function(request, settings) {
alert('Beginning ' + settings.dataType + ' request: ' + settings.url);
},
complete: function(request, status) {
alert('Request complete: ' + status);
},
error: function(request, status, error) {
alert(error);
}
});
IE will execute the beforeSend callback and the error callback. The error callback alerts with the message:
Error: This method cannot be called until the open method has been called.
My response header returns with Content-Type: text/javascript; charset=UTF-8.
What is going on with IE? I'm running the server on localhost, making a request from http://localhost:8080/psx to http://localhost:8080/helper. Maybe IE is blocking this request? I have tried installing Fiddler to analyze request traffic but it won't run on my machine because it's rather locked down. Firebug lets me, but everything seems good there.
Thanks for the help!!!
Alright, here's the fix! The request was using window.XMLHttpRequest(), which isn't working properly in IE8 for some reason. jQuery is not failing back to window.ActiveXObject("Microsoft.XMLHTTP") as it should.
Add this to your script somewhere before your AJAX call (only verified in IE8, not other IE's):
jQuery.ajaxSetup({
xhr: function() {
//return new window.XMLHttpRequest();
try{
if(window.ActiveXObject)
return new window.ActiveXObject("Microsoft.XMLHTTP");
} catch(e) { }
return new window.XMLHttpRequest();
}
});
Here's how I came to the solution:
Updated to jQuery 1.4.4 in case the issue was a bug that had been fixed.
Stepped through Firebug debugger and DevTools debugger until the results seemed to be drastically different.
On line 5899, the ajax() function creates the XmlHttpRequest object with the xhr() function. In Firefox, it was returning good data. In IE, this was returning with all fields being Error: This method cannot be called until the open method has been called.
I analyzed this function on line 5749, return new window.XMLHttpRequest();
I googled and came across this page that has the same problem and suggested the solution that works for me.
Official jQuery ticket: