I have to add customheaders to all ajax requests . I'm able to do this using the following code .Except in one case.
$.ajaxPrefilter(function (options) {
if (!options.beforeSend) {
options.beforeSend = function (xhr) {
xhr.setRequestHeader('Token', '1234');
}
}
});
Suppose if we are putting beforesend in $.ajax request , the above prefilter is not firing (example below). Can you please tell me how can I acheive it by keeping both?. Is there any way can we add header to xmlHttpRequest so that we can use for all ajax requests that are going from application?
$("#AdvancedserchClick").on("click", function () {
$.ajax({
async: false,
cache: false,
type: "POST",
url: getUrlWithTabId("#Url.Action("AdvancedSearch", "AdvancedSearch")"),
beforeSend: function () {
Load.show();
},
success: function (result) {
$("#advancedsearch").modal('show');
$("#advancedsearch").html(result);
},
complete: function () {
Load.hide();
}
});
});
You can achieve this by using the below code
$.ajax({
url: 'foo/bar',
headers: { 'x-my-custom-header': 'some value' }
});
Or you can use pre-filter would be an easy way of accomplishing this but this way all requests will get the custom header, unless the specific request overrides the beforeSend option.
$.ajaxPrefilter(function( options ) {
if ( !options.beforeSend) {
options.beforeSend = function (xhr) {
xhr.setRequestHeader('CUSTOM-HEADER-KEY', 'CUSTOM-HEADER-VALUE');
}
}
});
Hope this helps.
$.ajaxPrefilter(function( options, originalOptions, xhr ) {
xhr.setRequestHeader('Token', '1234');
});
Docs say :
jQuery.ajaxPrefilter( [dataTypes ], handler )
Description: Handle custom Ajax options or modify existing options before
each request is sent and before they are processed by $.ajax()
Related
I am currently migrating the use of ajax to the fetch, however I am needing a parameter/function the Ajax native beforeSend: function(). I would like to perform the same action without requiring an implementation in fetch (a creation of a new class for example)
jQuery $.ajax structure:
$.ajax({
url: '...',
type: 'post',
data: {...},
beforeSend: function() {
// perform the action..
},
success: function(response, status, xhr) {
// receive response data
}
});
JavaScript fetch structure:
fetch('...').then((response) => {
return response.text();
}).then((data) => {
console.log(data);
});
How do I determine such a function without needing an implementation or creating a new class on fetch. Is there any means or only implementation? because of my searches I only found implementations like CustomFetch (Is there a beforesend Javascript promise) and others.
Solved problem!
No need to implement and/or create a new fetch class. Using only parameters as "function inside function". I hope you can help others!
function ipGetAddress(format) {
requestFetch = function() {
// perform the action..
console.log('** beforeSend request fetch **');
return fetch.apply(this, arguments);
}
requestFetch(`https://api.ipify.org?format=${format}`).then((response) => {
return response.json();
}).then((data) => {
console.log(data.ip);
});
}
ipGetAddress('json') // return local ip address..
I have looked at various questions that talk about when Synchronous requests, how to return data from the Ajax request (with Promises and Callbacks) but nothing seems to answer what I am after.
var FacadeApi = ( function($) {
var endpoint = '/auth/',
self = this,
settings = {
isAuthenticated: false,
authkey: null
};
function init() {
$.ajax( {
url: self.endpoint,
dataType: 'json',
async: true
})
.done( function( `enter code here`data ) {
self.settings.authKey = data.authKey;
self.settings.isAuthenticated = true;
})
.fail( function( error ) {
});
}
var Facade = {
someRequest: function( ) {
$.ajax( {
url: someUri,
dataType: 'json',
data: { authKey: authKey }
})
.done( fuction( data ) {
// does stuff.
});
}
};
init();
return Facade;
}( jQuery ));
My module depends on requesting an authentication key and then having that as part of each request. Until this request is resolved, it can't be used. Which lead me to the async: false in the init function.
In this scenario, is it recommended to 'block' until the init call is completed? Could I achieve what I am after and keep the init request asynchronous?
So if i understand correctly,
You want to make sure that if someone calls somerequest() it should wait till you have the token , which is initiated in a separate request.
I suggest following pattern.
Do not call init() from the beginning.
when you need to call somerequest()
check if you have valid token value.
If token value is not there you can use $.When() such that somerequest() is only called when init() ajax call returns successfully.
If I have to leverage niceties of jQuery AJAX API and set my own custom settings for each ajax call my app makes like below:
Say I have a page which displays employee information within table by making ajax calls to some API.
define(["jQuery"], function($) {
var infoTable = function (options) {
function init() {
// Provide success callback
options.success_callback = "renderData";
getData();
}
function renderData() {
// This callback function won't be called as it is not
// in global scope and instead $.ajax will try to look
// for function named 'renderData' in global scope.
// How do I pass callbacks defined within requirejs define blocks?
}
function getData() {
$.ajax({
url: options.apiURL,
dataType: options.format,
data: {
format: options.format,
APIKey: options.APIKey,
source: options.source,
sourceData: options.sourceData,
count: options.count,
authMode: options.authMode
},
method: options.method,
jsonpCallback: options.jsonpCallback,
success: options.success_callback,
error: options.error_callback,
timeout: options.timeout
});
}
}
return {
init: init
}
}
How do I achieve this?
I know we can use JSONP request as require calls but that restricts me to using jsonp, making GET requests and all other features $.ajax offers.
This example would let you either use a default success callback, or provide an override, using:
success: options.successCallback || renderData
(The example uses jsfiddle rest URLs - this fact is unimportant, and stripped out the data object to keep the example short)
define("mymodule", ["jquery"], function($) {
function renderData() {
console.log("inside callback");
}
function getData(options) {
$.ajax({
url: options.apiURL,
dataType: options.format,
method: options.method,
jsonpCallback: options.jsonpCallback,
success: options.successCallback || renderData,
error: null,
timeout: options.timeout
});
}
return {
getData: getData
}
});
require(["mymodule"], function(m) {
console.log(m, m.getData({
apiURL: "/echo/json/"
}));
console.log(m, m.getData({
successCallback: function() { console.log("outside callback"); },
apiURL: "/echo/json/"
}));
});
Would print:
GET http://fiddle.jshell.net/echo/json/ 200 OK 263ms
Object { getData=getData()} undefined
GET http://fiddle.jshell.net/echo/json/ 200 OK 160ms
Object { getData=getData()} undefined
inside callback
outside callback
For some reason the ajax requests I make on the website I'm working on abort half of the time. This is resolved when I set a timeout for the ajax request like shown below.
$.ajax({
url: "/question/why_wont_it_work",
timeout : 1000,
success: function(){ /*do stuff*/ }
});
Sadly the timeout fix doesn't seem to work with the jquery autocomplete. I'm using it like this:
$( "#questionTags" ).autocomplete({
source: "/question/tags",
timeout: 1000,
select: function(event, ui) { /*do stuff*/ },
});
I checked the jQueryUI documentation on the website and didn't see the timeout option there either. Now this is pretty annoying since half of the time my request will abort and I won't get the results
I want. Is there a way around this?
Thanks in advance.
You can supply an arbitrary function to the source parameter. So you could manually make an AJAX request and specify the timeout option:
var xhr = null; /* To prevent multiple calls from happening while one is in progress */
$("#questionTags").autocomplete({
source: function (request, response) {
if (!xhr) {
xhr = $.ajax({
url: "/question/tags",
timeout: 20000,
data: request,
dataType: "json",
success: function (data) {
xhr = null;
response(data);
},
error: function () {
response([]);
}
});
}
},
select: function(event, ui) { /*do stuff*/ },
});
But I'm with #El Ronnoco, you probably want to seriously speed up your request. 20 seconds is a long time to wait.
If source is a string, jQuery autocomplete does the code shown below to load the data, so it doesn't set a timeout.
You could set the timeout globally by using ajaxSetup like this:
$.ajaxSetup({
timeout: 20000,
});
But that would affect all your ajax requests.
Code from jquery.ui.autocomplete.js :: _initSource
self.xhr = $.ajax({
url: url,
data: request,
dataType: "json",
context: {
autocompleteRequest: ++requestIndex
},
success: function( data, status ) {
if ( this.autocompleteRequest === requestIndex ) {
response( data );
}
},
error: function() {
if ( this.autocompleteRequest === requestIndex ) {
response( [] );
}
}
});
$target.autocomplete('/question/why_wont_it_work',{
delay: 2000
});
I'm working on a component for Joomla 1.7, and Joomla 1.7 works with Mootools 1.3. Before that, the correct way in mootools was Ajax class. But in Mootools, as I read, I must use Request class.
Ok, when I try to use the Request class and take a look with Google Inspector debuging step by step the Request definition and Request send() call. I can see that, it execs the send but it does nothing (ignores onSuccess, ignores OnException, etc).
And if I look on chrome javascript console there's nothing.
function addValue(value) {
var id = $('selectedval').getProperty('value');
var url = 'index.php?option=com_kaltura&controller=fieldsmanager&task=additem&tmpl=component';
var req = new Request(url, {
method: 'post',
data: {
'id': id,
'value': value
},
onRequest: function(event, xhr) {alert('gogogo'); },
onFailure: function(xhr) { alert('failure'.xhr); },
onException: function(test) {alert(test); },
onSuccess: function(data) {
loadFieldList(data);
}
});
req.send();
}
the api has changed from 1.1x to 1.2 -> Request now takes a single argument object that overloads all options you need, INCLUDING url - which used to be arguments[0] before.
In other words - move the url from there into a property of the options object:
new Request({
url: url,
method: 'post',
data: {
'id': id,
'value': value
},
onRequest: function(event, xhr) {alert('gogogo'); },
onFailure: function(xhr) { alert('failure'.xhr); },
onException: function(test) {alert(test); },
onSuccess: function(data) {
loadFieldList(data);
}
}).send();