Performing javascript action before every http request - javascript

Is it possible to perform an action before every http request sent upon clicking an a-href tag? I would like to perform the action before every referred http request as well (eg requests for images/scripts in the DOM). Thanks!

It can be achieved for every HTTP ajax request.
Note : Dummy requests in examples are made to HTTP Bin.
JAVASCRIPT:
References : JS XMLHttpRequest
(function init()
{
XMLHttpRequest.prototype._open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password){
initialChanges();
this._open(method, url, async, user, password);
};
})();
function initialChanges()
{
alert("Making a Javascript ajax request.");
}
function makeRequestViaXHR()
{
var req = new XMLHttpRequest();
req.open("GET","https://httpbin.org/get",false,null,null);
req.onreadystatechange=function(){
if(req.readyState === 4)
{
if(req.status === 200)
{
console.log(req.responseText);
}
else
{
console.log("Request Failed");
}
}
};
req.send();
}
<button onclick="makeRequestViaXHR()">Make a dummy ajax request via Javascript</button>
JQUERY:
References : jQuery ajax, jQuery .ajaxSend
(function init()
{
$(document).ajaxSend(function(event,xhr,settings){
alert("Making a jQuery ajax request.");
});
})();
function makeRequestViaJquery()
{
$.ajax({
url:"https://httpbin.org/get",
method:"GET",
async:true,
success:function(response){
console.log(response);
},
error:function(error){
console.log(error);
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="makeRequestViaJquery()">Make a dummy ajax request via jQuery</button>
In case of navigating to other pages, downloading files or mail addresses via <a> tag, execute the method on click using addEventListener.
References : HTML Element Subinterfaces
document.addEventListener("click", function(event){
var elem = event.target;
if(elem instanceof HTMLAnchorElement) //For <a> tag
{
executeThis();
}
});
function executeThis()
{
alert("Element is clicked");
}
Click this anchor element
Download Image
Scripts execute only after the DOM is loaded. If some function need to be executed before loading the images, you need to add the method with a script tag before every img element. Refer this for more info.

Related

How to abort ajax request on page refresh

I have a form, on submit of that I am making an ajax request which is sometimes taking time to get the request, so what I am trying to do is whenever user refresh or clicks back button of the browser after form submitting i want to abort that ajax call
What I am doing is
$("#formId").submit(function(event) {
event.preventDefault();
var xhr = $.ajax({
url : "Drilldown",
method : "GET",
success : function(data) {
// here doing ,my stuff
},
complete : function() {
$('.loader').hide();
$('.overlay').hide();
}
});
window.onbeforeunload = function() {
return "some message"; // here when user clicks on leave then want to abort like `xhr.abort`
};
});
whenever the user clicks on leave I want to abort my ajax request
How can I do that?
**I specifically want to do that when ever form submit and once form is submitted,i want to abort that function also onbeforeunload **
You can directly xhr.abort() in "onbeforeunload" event handler method:
// Define xhr variable outside so all functions can have access to it
var xhr = null;
$("#formId").submit(function(event) {
event.preventDefault();
xhr = $.ajax({
url: "Drilldown",
method: "GET",
success: function(data) {
// here doing ,my stuff
},
complete: function() {
$('.loader').hide();
$('.overlay').hide();
}
});
});
window.onbeforeunload = onUnload;
function onUnload() {
if(xhr) xhr.abort();
return "some message";
};
call below method to abort ajax call
xhr.abort()

Executing a url without opening it on the browser in Javascript / Jquery

I have a local page that pulls data from a database and sends out a message. So I'm trying to have this page executed using javascript on "success" of another function. The problem is everything I've tried doesn't seem to execute that page, while the only success I've had on executing that page is using a window pop up, which is not desired.
This is the pop up code (undesired):
function sendMsg(){
var wnd = window.open("http://localhost/url");
if(wnd){
setTimeout(function () { wnd.close();}, 4000);
}
}
sendMsg();
And these are the codes I've tried but didn't execute the url:
$.get("http://localhost/url")
And this one which is from another answer here on SO.
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
var response = xmlhttp.responseText; returned value
}
}
xmlhttp.open("GET","http://localhost/url",true);
xmlhttp.send();
How can I have this URL executed without opening it on the browser in any way?
Just to be clear, I know the other two codes didn't work because I would have received a message.
if you really need a return data/page from get
you should do something like this.
$.get( "url", function( data ) {
console.log(data); // return data/page
alert( "Done load." );
});
# use ajax
$.ajax({
url: "url",
type: "GET",
success : function( data ){
console.log(data); // return data/page
alert("Done LOad");
}
});
anything else can refer : https://api.jquery.com/jquery.get/
I believe jQuery's load() method may be useful for this. For example, have a div in your HTML and just set it to hidden in the CSS.
jQuery load() Method
HTML:
<div id='myHiddenPage'></div>
CSS:
#myHiddenPage {
display: none;
}
jQUERY:
$(funtion() {
$('#myHiddenPage').load('www.myurl.com');
});

How Do I Stop a Web Service Method That Has Been Executed [duplicate]

Is it possible that using jQuery, I cancel/abort an Ajax request that I have not yet received the response from?
Most of the jQuery Ajax methods return an XMLHttpRequest (or the equivalent) object, so you can just use abort().
See the documentation:
abort Method (MSDN). Cancels the current HTTP request.
abort() (MDN). If the request has been sent already, this method will abort the request.
var xhr = $.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston",
success: function(msg){
alert( "Data Saved: " + msg );
}
});
//kill the request
xhr.abort()
UPDATE:
As of jQuery 1.5 the returned object is a wrapper for the native XMLHttpRequest object called jqXHR. This object appears to expose all of the native properties and methods so the above example still works. See The jqXHR Object (jQuery API documentation).
UPDATE 2:
As of jQuery 3, the ajax method now returns a promise with extra methods (like abort), so the above code still works, though the object being returned is not an xhr any more. See the 3.0 blog here.
UPDATE 3: xhr.abort() still works on jQuery 3.x. Don't assume the update 2 is correct. More info on jQuery Github repository.
You can't recall the request but you can set a timeout value after which the response will be ignored. See this page for jquery AJAX options. I believe that your error callback will be called if the timeout period is exceeded. There is already a default timeout on every AJAX request.
You can also use the abort() method on the request object but, while it will cause the client to stop listening for the event, it may probably will not stop the server from processing it.
Save the calls you make in an array, then call xhr.abort() on each.
HUGE CAVEAT: You can abort a request, but that's only the client side. The server side could still be processing the request. If you are using something like PHP or ASP with session data, the session data is locked until the ajax has finished. So, to allow the user to continue browsing the website, you have to call session_write_close(). This saves the session and unlocks it so that other pages waiting to continue will proceed. Without this, several pages can be waiting for the lock to be removed.
It's an asynchronous request, meaning once it's sent it's out there.
In case your server is starting a very expensive operation due to the AJAX request, the best you can do is open your server to listen for cancel requests, and send a separate AJAX request notifying the server to stop whatever it's doing.
Otherwise, simply ignore the AJAX response.
AJAX requests may not complete in the order they were started. Instead of aborting, you can choose to ignore all AJAX responses except for the most recent one:
Create a counter
Increment the counter when you initiate AJAX request
Use the current value of counter to "stamp" the request
In the success callback compare the stamp with the counter to check if it was the most recent request
Rough outline of code:
var xhrCount = 0;
function sendXHR() {
// sequence number for the current invocation of function
var seqNumber = ++xhrCount;
$.post("/echo/json/", { delay: Math.floor(Math.random() * 5) }, function() {
// this works because of the way closures work
if (seqNumber === xhrCount) {
console.log("Process the response");
} else {
console.log("Ignore the response");
}
});
}
sendXHR();
sendXHR();
sendXHR();
// AJAX requests complete in any order but only the last
// one will trigger "Process the response" message
Demo on jsFiddle
We just had to work around this problem and tested three different approaches.
does cancel the request as suggested by #meouw
execute all request but only processes the result of the last submit
prevents new requests as long as another one is still pending
var Ajax1 = {
call: function() {
if (typeof this.xhr !== 'undefined')
this.xhr.abort();
this.xhr = $.ajax({
url: 'your/long/running/request/path',
type: 'GET',
success: function(data) {
//process response
}
});
}
};
var Ajax2 = {
counter: 0,
call: function() {
var self = this,
seq = ++this.counter;
$.ajax({
url: 'your/long/running/request/path',
type: 'GET',
success: function(data) {
if (seq === self.counter) {
//process response
}
}
});
}
};
var Ajax3 = {
active: false,
call: function() {
if (this.active === false) {
this.active = true;
var self = this;
$.ajax({
url: 'your/long/running/request/path',
type: 'GET',
success: function(data) {
//process response
},
complete: function() {
self.active = false;
}
});
}
}
};
$(function() {
$('#button').click(function(e) {
Ajax3.call();
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="button" type="button" value="click" />
In our case we decided to use approach #3 as it produces less load for the server. But I am not 100% sure if jQuery guarantees the call of the .complete()-method, this could produce a deadlock situation. In our tests we could not reproduce such a situation.
It is always best practice to do something like this.
var $request;
if ($request != null){
$request.abort();
$request = null;
}
$request = $.ajax({
type : "POST", //TODO: Must be changed to POST
url : "yourfile.php",
data : "data"
}).done(function(msg) {
alert(msg);
});
But it is much better if you check an if statement to check whether the ajax request is null or not.
Just call xhr.abort() whether it's jquery ajax object or native XMLHTTPRequest object.
example:
//jQuery ajax
$(document).ready(function(){
var xhr = $.get('/server');
setTimeout(function(){xhr.abort();}, 2000);
});
//native XMLHTTPRequest
var xhr = new XMLHttpRequest();
xhr.open('GET','/server',true);
xhr.send();
setTimeout(function(){xhr.abort();}, 2000);
You can abort any continuous ajax call by using this
<input id="searchbox" name="searchbox" type="text" />
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
var request = null;
$('#searchbox').keyup(function () {
var id = $(this).val();
request = $.ajax({
type: "POST", //TODO: Must be changed to POST
url: "index.php",
data: {'id':id},
success: function () {
},
beforeSend: function () {
if (request !== null) {
request.abort();
}
}
});
});
</script>
As many people on the thread have noted, just because the request is aborted on the client-side, the server will still process the request. This creates unnecessary load on the server because it's doing work that we've quit listening to on the front-end.
The problem I was trying to solve (that others may run in to as well) is that when the user entered information in an input field, I wanted to fire off a request for a Google Instant type of feel.
To avoid firing unnecessary requests and to maintain the snappiness of the front-end, I did the following:
var xhrQueue = [];
var xhrCount = 0;
$('#search_q').keyup(function(){
xhrQueue.push(xhrCount);
setTimeout(function(){
xhrCount = ++xhrCount;
if (xhrCount === xhrQueue.length) {
// Fire Your XHR //
}
}, 150);
});
This will essentially send one request every 150ms (a variable that you can customize for your own needs). If you're having trouble understanding what exactly is happening here, log xhrCount and xhrQueue to the console just before the if block.
I was doing a live search solution and needed to cancel pending requests that may have taken longer than the latest/most current request.
In my case I used something like this:
//On document ready
var ajax_inprocess = false;
$(document).ajaxStart(function() {
ajax_inprocess = true;
});
$(document).ajaxStop(function() {
ajax_inprocess = false;
});
//Snippet from live search function
if (ajax_inprocess == true)
{
request.abort();
}
//Call for new request
Just use ajax.abort() for example you could abort any pending ajax request before sending another one like this
//check for existing ajax request
if(ajax){
ajax.abort();
}
//then you make another ajax request
$.ajax(
//your code here
);
there is no reliable way to do it, and I would not even try it, once the request is on the go; the only way to react reasonably is to ignore the response.
in most cases, it may happen in situations like: a user clicks too often on a button triggering many consecutive XHR, here you have many options, either block the button till XHR is returned, or dont even trigger new XHR while another is running hinting the user to lean back - or discard any pending XHR response but the recent.
The following code shows initiating as well as aborting an Ajax request:
function libAjax(){
var req;
function start(){
req = $.ajax({
url: '1.php',
success: function(data){
console.log(data)
}
});
}
function stop(){
req.abort();
}
return {start:start,stop:stop}
}
var obj = libAjax();
$(".go").click(function(){
obj.start();
})
$(".stop").click(function(){
obj.stop();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" class="go" value="GO!" >
<input type="button" class="stop" value="STOP!" >
If xhr.abort(); causes page reload,
Then you can set onreadystatechange before abort to prevent:
// ↓ prevent page reload by abort()
xhr.onreadystatechange = null;
// ↓ may cause page reload
xhr.abort();
I had the problem of polling and once the page was closed the poll continued so in my cause a user would miss an update as a mysql value was being set for the next 50 seconds after page closing, even though I killed the ajax request, I figured away around, using $_SESSION to set a var won't update in the poll its self until its ended and a new one has started, so what I did was set a value in my database as 0 = offpage , while I'm polling I query that row and return false; when it's 0 as querying in polling will get you current values obviously...
I hope this helped
I have shared a demo that demonstrates how to cancel an AJAX request-- if data is not returned from the server within a predefined wait time.
HTML :
<div id="info"></div>
JS CODE:
var isDataReceived= false, waitTime= 1000;
$(function() {
// Ajax request sent.
var xhr= $.ajax({
url: 'http://api.joind.in/v2.1/talks/10889',
data: {
format: 'json'
},
dataType: 'jsonp',
success: function(data) {
isDataReceived= true;
$('#info').text(data.talks[0].talk_title);
},
type: 'GET'
});
// Cancel ajax request if data is not loaded within 1sec.
setTimeout(function(){
if(!isDataReceived)
xhr.abort();
},waitTime);
});
This is my implementation based on many answers above:
var activeRequest = false; //global var
var filters = {...};
apply_filters(filters);
//function triggering the ajax request
function apply_filters(filters){
//prepare data and other functionalities
var data = {};
//limit the ajax calls
if (activeRequest === false){
activeRequest = true;
}else{
//abort if another ajax call is pending
$request.abort();
//just to be sure the ajax didn't complete before and activeRequest it's already false
activeRequest = true;
}
$request = $.ajax({
url : window.location.origin + '/your-url.php',
data: data,
type:'POST',
beforeSend: function(){
$('#ajax-loader-custom').show();
$('#blur-on-loading').addClass('blur');
},
success:function(data_filters){
data_filters = $.parseJSON(data_filters);
if( data_filters.posts ) {
$(document).find('#multiple-products ul.products li:last-child').after(data_filters.posts).fadeIn();
}
else{
return;
}
$('#ajax-loader-custom').fadeOut();
},
complete: function() {
activeRequest = false;
}
});
}

show loading status with ajax call

I'm looking for a JavaScript solution to show some sort of status while an ajax request is taking place. I tried document.getElementById("status").innerHTML = "<h2>Loading....</h2>"; but that didn't work. Any ideas?
function codesDelete(id) {
var ajax;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
} else {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
ajax.onreadystatechange = function() {
if (ajax.readyState === 4 && ajax.status === 200) {
document.getElementById("status").innerHTML = "<h2>Data Deleted!</h2>";
}
}
// this is what i tried
document.getElementById("status").innerHTML = "<h2>Loading....</h2>";
ajax.open("GET", "code.php?id=" + id, true);
ajax.send();
setTimeout(function() {
document.getElementById("status").style.display = "none";
}, 3000);
}
You can use JQuery's when/done. Start your status indicator and then use when/done like this:
// start the status indicator wherever it's appropriate
StartStatusIndicator();
//Make your ajax call
$.when($.ajax({
type: "POST",
...more stuff...
success: function (json) {
...even more stuff...
}
})).done(function () {
KillYourStatusIndicator();
});
The code inside done gets fired when the ajax call is finished.
Another method you could do is to use the beforeSend and complete callbacks on jQuery.ajax, like so:
$.ajax({
beforeSend:function(){
// Create and insert your loading message here as you desire
// For example, a version of what you were trying to do would be:
$("#status").html("<h2>Loading....</h2>");
},
// ... whatever other things you need, such as a success callback, data, url, etc
complete: function(){
// Remove your loading message here, for example:
$("#status").html("");
}
});
As the names suggest, beforeSend will be executed before the AJAX call is made. Complete will execute, regardless whether the AJAX succeeded or failed, after the call is finished.

checking the page exist or not using javascript [duplicate]

I have a link: Hello.
When someone clicks the link I'd like to check via JavaScript if the page the href-attribute points to exists or not. If the page exists the browser redirects to that page ("www.example.com" in this example) but if the page doesn't exist the browser should redirect to another URL.
It depends on whether the page exists on the same domain or not. If you're trying to determine if a page on an external domain exists, it won't work – browser security prevents cross-domain calls (the same-origin policy).
If it is on the same domain however, you can use jQuery like Buh Buh suggested. Although I'd recommend doing a HEAD-request instead of the GET-request the default $.ajax() method does – the $.ajax() method will download the entire page. Doing a HEAD request will only return the headers and indicate whether the page exists (response codes 200 - 299) or not (response codes 400 - 499). Example:
$.ajax({
type: 'HEAD',
url: 'http://yoursite.com/page.html',
success: function() {
// page exists
},
error: function() {
// page does not exist
}
});
See also: http://api.jquery.com/jQuery.ajax/
A pretty good work around is to proxy. If you don't have access to a server side you can use YQL. Visit: http://developer.yahoo.com/yql/console/
From there you can do something like: select * from htmlstring where url="http://google.com". You can use the "REST query" they have on that page as a starting point for your code.
Here's some code that would accept a full URL and use YQL to detect if that page exists:
function isURLReal(fullyQualifiedURL) {
var URL = encodeURIComponent(fullyQualifiedURL),
dfd = $.Deferred(),
checkURLPromise = $.getJSON('http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20htmlstring%20where%20url%3D%22' + URL + '%22&format=json');
checkURLPromise
.done(function(response) {
// results should be null if the page 404s or the domain doesn't work
if (response.query.results) {
dfd.resolve(true);
} else {
dfd.reject(false);
}
})
.fail(function() {
dfd.reject('failed');
});
return dfd.promise();
}
// usage
isURLReal('http://google.com')
.done(function(result) {
// yes, or request succeded
})
.fail(function(result) {
// no, or request failed
});
Update August 2nd, 2017
It looks like Yahoo deprecated "select * from html", although "select * from htmlstring" does work.
Based on the documentation for XMLHttpRequest:
function returnStatus(req, status) {
//console.log(req);
if(status == 200) {
console.log("The url is available");
// send an event
}
else {
console.log("The url returned status code " + status);
// send a different event
}
}
function fetchStatus(address) {
var client = new XMLHttpRequest();
client.onreadystatechange = function() {
// in case of network errors this might not give reliable results
if(this.readyState == 4)
returnStatus(this, this.status);
}
client.open("HEAD", address);
client.send();
}
fetchStatus("/");
This will however only work for URLs within the same domain as the current URL. Do you want to be able to ping external services? If so, you could create a simple script on the server which does your job for you, and use javascript to call it.
If it is in the same domain, you can make a head request with the xmlhttprequest object [ajax] and check the status code.
If it is in another domain, make an xmlhttprequest to the server and have it make the call to see if it is up.
why not just create a custom 404 handler on the web server? this is probably the more "good-bear" way to do this.
$.ajax({
url: "http://something/whatever.docx",
method: "HEAD",
statusCode: {
404: function () {
alert('not found');
},
200: function() {
alert("foundfile exists");
}
}
});
If you are happy to use jQuery you could do something like this.
When the page loads make an ajax call for each link. Then just replace the href of all the links which fail.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
<!--
$.fn.checkPageExists = function(defaultUrl){
$.each(this, function(){
var $link = $(this);
$.ajax({
url: $link.attr("href"),
error: function(){
$link.attr("href", defaultUrl);
}
});
});
};
$(document).ready(function(){
$("a").checkPageExists("default.html");
});
//-->
</script>
You won't be able to use an ajax call to ping the website because of same-origin policy.
The best way to do it is to use an image and if you know the website you are calling has a favicon or some sort of icon to grab, you can just use an html image tag and use the onerror event.
Example:
function pingImgOnWebsite(url) {
var img = document.createElement('img');
img.style.visibility = 'hidden';
img.style.position = 'fixed';
img.src = url;
img.onerror = continueBtn; // What to do on error function
document.body.appendChild(img);
}
Another way to do this is is with PHP.
You could add
<?php
if (file_exists('/index.php'))
{
$url = '/index.php';
} else {
$url = '/notindex.php';
}
?>
And then
<a href="<?php echo $url; ?>Link</a>

Categories

Resources