I am working on a scenario, where i need to cancel third party library request based on some condition and then unblock if condition evaluates to false. Let us assume that third party URL is being loaded with following URL:
https://cdn-thirdparty.com/...
Now, once it is loaded, it captures user clicks on the application and sends data as another URL:
https://cdn-info-thirdpart.com/...
Now, say i want to block all the requests to URL which contains thirdparty in it.. How do i achieve this in Vanilla Javascript...
P.S: I do not have access to remove the library from code, instead i have to do some engineering that requests are getting blocked based on some conditions(we can assume any) and then getting unblocked on falsy condition.
The code i tried to intercept all XMLHttpRequest is as below and i do get URL, method of call but i need to block it now and then unblock.
let oldXHROpen = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
// do something with the method, url and etc.
this.addEventListener('load', function() {
// do something with the response text
console.log('load: ' + url, method);
});
return oldXHROpen.apply(this, arguments);
}
Source of above code: https://medium.com/#gilfink/quick-tip-creating-an-xmlhttprequest-interceptor-1da23cf90b76
Related
I have a website where I need to update a status.
Like for a flight, you are departing, cruise or landed.
I want to be able to refresh the status without having my viewers to have and reload the whole page. I know there is a way to do it with AJAX and jQuery, but I don't have any understanding of how that works. I also don't want them to have and click a button.
If anybody knows how that would be done I much appreciate it!
This is typically achieved with a technique called AJAX. This technique loads data asynchronously (in the background) so it can update your content without needing to reload the page.
The easiest way to implement AJAX is with the jQuery load() method. This method provides a simple way to load data asynchronous from a web server and place the returned HTML into the selected element. The basic syntax of this method is: $(selector).load(url, data, complete); where the arguments are:
selector the existing HTML element you want to load the data into
url a string containing the URL to which the request is sent
data (optional) a plain object or string that is sent to the server with the request
complete (optional) a callback function that is executed when the request completes
The required URL parameter specifies the URL of the file you want to load.
The optional data parameter allows you to specify data (i.e. key/value pairs) that is sent to the web server along with the request. The optional complete parameter can be used to reference a callback function. The callback is fired once for each selected element.
A visualisation:
A simple example of using load(), where we load data dynamically when a button is pressed:
DEMO
// no need to specify document ready
$(function(){
// optional: don't cache ajax to force the content to be fresh
$.ajaxSetup ({
cache: false
});
// specify loading spinner
var spinner = "<img src='http://i.imgur.com/pKopwXp.gif' alt='loading...' />";
// specify the server/url you want to load data from
var url = "http://fiddle.jshell.net/dvb0wpLs/show/";
// on click, load the data dynamically into the #result div
$("#loadbasic").click(function(){
$("#result").html(spinner).load(url);
});
});
If you don't want to use the jQuery library, you can also use plain Javascript. Loading content is slightly more difficult that way. Here is an example of how to do it with javascript only.
To learn more about AJAX, you can take a look at https://www.w3schools.com/xml/ajax_intro.asp
Suppose you want to display some live feed content (say livefeed.txt) on you web page without any page refresh then the following simplified example is for you.
In the below html file, the live data gets updated on the div element of id "liveData"
index.html
<!DOCTYPE html>
<html>
<head>
<title>Live Update</title>
<meta charset="UTF-8">
<script type="text/javascript" src="autoUpdate.js"></script>
</head>
<div id="liveData">
<p>Loading Data...</p>
</div>
</body>
</html>
Below autoUpdate.js reads the live data using XMLHttpRequest object and updates the html div element on every 1 second. I have given comments on most part of the code for better understanding.
autoUpdate.js
window.addEventListener('load', function()
{
var xhr = null;
getXmlHttpRequestObject = function()
{
if(!xhr)
{
// Create a new XMLHttpRequest object
xhr = new XMLHttpRequest();
}
return xhr;
};
updateLiveData = function()
{
var now = new Date();
// Date string is appended as a query with live data
// for not to use the cached version
var url = 'livefeed.txt?' + now.getTime();
xhr = getXmlHttpRequestObject();
xhr.onreadystatechange = evenHandler;
// asynchronous requests
xhr.open("GET", url, true);
// Send the request over the network
xhr.send(null);
};
updateLiveData();
function evenHandler()
{
// Check response is ready or not
if(xhr.readyState == 4 && xhr.status == 200)
{
dataDiv = document.getElementById('liveData');
// Set current data text
dataDiv.innerHTML = xhr.responseText;
// Update the live data every 1 sec
setTimeout(updateLiveData(), 1000);
}
}
});
For testing purpose: Just write some thing in the livefeed.txt - You will get updated the same in index.html without any refresh.
livefeed.txt
Hello
World
blah..
blah..
Note: You need to run the above code on the web server (ex: http://localhost:1234/index.html) not as a client html file (ex: file:///C:/index.html).
You can read about jQuery Ajax from official jQuery Site:
https://api.jquery.com/jQuery.ajax/
If you don't want to use any click event then you can set timer for periodically update.
Below code may be help you just example.
function update() {
$.get("response.php", function(data) {
$("#some_div").html(data);
window.setTimeout(update, 10000);
});
}
Above function will call after every 10 seconds and get content from response.php and update in #some_div.
If you want to know how ajax works, it is not a good way to use jQuery directly. I support to learn the native way to send a ajax request to the server, see something about XMLHttpRequest:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://some.com");
xhr.onreadystatechange = function () {}; // do something here...
xhr.send();
I have series of OData calls which I make from JavaScript file (myfile.js) using Promises like shown below. The main entry point is the function MakePreferredCustomer(AccountNo). This function is called on load of a web page Page1.htm, which loads the JavaScript file myfile.js also. These series of OData calls (its more than the 5 shown below) take around 180-200 seconds to complete. This is async so, page load of Page1.htm is not affected. Also user does not come to know that these calls are happening in the background (which is a requirement to do this without asking user). But the problem is - what happens if user switches to some other page from this Page before the 180-200 seconds. I am not sure if the async tasks keep on happening in the background or will it stop in between (depending on when user moves away from Page1.htm)?
Is there a definite way this will behave or will this change depending on browser being used or some other external criteria? Please guide.
void MakePreferredCustomer(AccountNo)
{
GetAccountDataFromServer() //This internally does " return Common.MakeWebApiRequest"
.then(HandleAccountDataResponse(request){
//Parse the response using JSON.Parse() and get account no
//Make WebApiRequest to get more details using account no
return Common.MakeWebApiRequest("GET", uri, additionalAccountData, headers);
})
.then(HandleAdditionalAccountDetails(request){
//Parse the response using JSON.Parse() and get additional acc details
//Store these details in additional variables in this function scope
//Make OData call to get Product Details
return Common.MakeWebApiRequest("GET", uri, Productdata, headers);
})
.then(HandleProductDetails(request){
//Parse the response using JSON.Parse() and get product details
//Check if this account had earlier porchased this product.
//Make OData call to get no of times this product should be purchased to become preferred customer
return Common.MakeWebApiRequest("GET", uri, PolicyData, headers);
}) .then(HandlePolicyDetails(request){
//Parse the response using JSON.Parse() and get policy details
//Check No if times prodocut should be bought and how may times this account has bought
//if condition meet, update preferred customers detials with this account as per below OData call
Common.MakeWebApiRequest("POST", uri, ThisAccountIsNewPreferredCustomerData, headers);
})
.catch(HandleException(e){
})
}
Each of the Functions call a common function MakeWebAPIRequest:
Common.MakeWebApiRequest = function (action, uri, data, headers)
{
//Do basci checks in input arguments
return new Promise(function (resolve, reject)
{
var request = new XMLHttpRequest();
request.open(action, encodeURI(uri), true); //async call
//Set OData specific headers using request.setRequestHeader
request.onreadystatechange = function ()
{
if (this.readyState === 4)
{
//Do Handling
}
}
if ("POST" === action && data === "")
{
request.send();
}
else if ("GET" === action)
{
request.send();
}
else
{
request.send(JSON.stringify(data));
}
});
}
When the user navigates away, the XMLHttpRequests will be aborted (or at least ignored on the client side), and the load handlers will be dropped and never executed. So no, javascript processes do not continue to work in the background.
The async requests, once initiated, will continue. As well, the promise handlers will also get invoked and run when the dependent Promise fulfills (or is rejected).
If these processes are independent of the content on Page1.html, then you should be okay. If there is a dependency (example, when one of your promise handlers kick-off and they rely on data available within Page1) then you will have to find a way to put those dependencies within the handlers or preserve what you need through closures.
How to issue request
PUT /user/someuser1
and parse result in browser?
Note that AJAX solution in this answer https://stackoverflow.com/a/2153931/258483 does something different: it passes the answer to closure function, while I need synchronous solution, i.e. pass the answer to entire browser window.
Like the following code
location.href = '/user/someuser1';
does with GET request.
UPDATE
I did the following way:
<script type="text/javascript">
function execute2() {
url = '/user/' +$('#screenname2').val();
$.ajax({
url: url,
method: 'GET', // PUT
converters: {"text json": window.String}
}).done(
function(http) {
document.open();
document.write(http);
document.close();
window.history.pushState(null, "New User", url);
}
);
}
</script>
<p>PUT /user/<input type="text" value="someuser1" id="screenname2"> <input type="button" value="Go" onclick="execute2()"></p>
Used GET for test purposes.
Unfortunately, my service returns JSON and it displays differently than if I get it with location.href: in my case it shows as plain text, while if location.href it displays with indentation.
Also, I can't navigate back to initial page -- it changes address in address bar, but not shows the content of referrer page...
HTML doesn't provide any means to make a PUT request, only GET and POST.
The only way to make one is with JavaScript and XMLHttpRequest. Then the only way you can handle the response you get is to process it with JavaScript.
Therefore, the closest you can come is to:
Make the request with XHR
Use the callback to read the response
Replace the content of the current document with the content of the response using DOM
Update the URL using pushState
I'm pretty new to javascript and am working on an embedded system which decodes video over IP.
I have written a small app for setting up and changing channels using javascript and included a key handler for remote controls and an event handler so I can take some action or present a message if video stops or the network goes down, but now I also want to set up an automatic HTTP POST that gets sent when I change channel to include some data about the device and the url currently being played.
This is a small embedded hardware device running busybox, so I can't use Ajax or add any other normal web technologies, I just need to use Javascript to send a HTTP POST triggered by events I am monitoring, so my first goal is to be able to press a button and send that POST message then work out when to trigger it later.
Anyone familiar with doing such things that can give me a quick overview of how to send a post to a known listening device/location and include data in it?
Many thanks
This is easy if your Javascript engine supports XMLHttpRequest (XHR), which is ubiquitous on the web. Google it or see this page for details. I've provided a code snippet below. Read it carefully, particularly the comments on "async" being true and closures in response handlers. Also, this code is super lightweight as far as Javascript goes and I would expect it would work fine on just about any contemporary hardware footprint.
var url = "http://www.google.com/";
var method = "POST";
var postData = "Some data";
// You REALLY want shouldBeAsync = true.
// Otherwise, it'll block ALL execution waiting for server response.
var shouldBeAsync = true;
var request = new XMLHttpRequest();
// Before we send anything, we first have to say what we will do when the
// server responds. This seems backwards (say how we'll respond before we send
// the request? huh?), but that's how Javascript works.
// This function attached to the XMLHttpRequest "onload" property specifies how
// the HTTP response will be handled.
request.onload = function () {
// Because of javascript's fabulous closure concept, the XMLHttpRequest "request"
// object declared above is available in this function even though this function
// executes long after the request is sent and long after this function is
// instantiated. This fact is CRUCIAL to the workings of XHR in ordinary
// applications.
// You can get all kinds of information about the HTTP response.
var status = request.status; // HTTP response status, e.g., 200 for "200 OK"
var data = request.responseText; // Returned data, e.g., an HTML document.
}
request.open(method, url, shouldBeAsync);
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
// Or... request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
// Or... whatever
// Actually sends the request to the server.
request.send(postData);
I have two HTML pages that work in a parent-child relationship in this way:
The first one has a button which does two things: First it requests data from the database via an AJAX call. Second it directs the user to the next page with the requested data, which will be handled by JavaScript to populate the second page.
I can already obtain the data via an ajax call and put it in a JSON array:
$.ajax({
type: "POST",
url: get_data_from_database_url,
async:false,
data: params,
success: function(json)
{
json_send_my_data(json);
}
});
function json_send_my_data(json)
{
//pass the json object to the other page and load it
}
I assume that on the second page, a "document ready" JavaScript function can easily handle the capture of the passed JSON object with all the data. The best way to test that it works is for me to use alert("My data: " + json.my_data.first_name); within the document ready function to see if the JSON object has been properly passed.
I simply don't know a trusted true way to do this. I have read the forums and I know the basics of using window.location.url to load the second page, but passing the data is another story altogether.
session cookie may solve your problem.
On the second page you can print directly within the cookies with Server-Script tag or site document.cookie
And in the following section converting Cookies in Json again
How about?
Warning: This will only work for single-page-templates, where each pseudo-page has it's own HTML document.
You can pass data between pages by using the $.mobile.changePage() function manually instead of letting jQuery Mobile call it for your links:
$(document).delegate('.ui-page', 'pageinit', function () {
$(this).find('a').bind('click', function () {
$.mobile.changePage(this.href, {
reloadPage : true,
type : 'post',
data : { myKey : 'myVal' }
});
return false;
});
});
Here is the documentation for this: http://jquerymobile.com/demos/1.1.1/docs/api/methods.html
You can simply store your data in a variable for the next page as well. This is possible because jQuery Mobile pages exist in the same DOM since they are brought into the DOM via AJAX. Here is an answer I posted about this not too long ago: jQuery Moblie: passing parameters and dynamically load the content of a page
Disclaimer: This is terrible, but here goes:
First, you will need this function (I coded this a while back). Details here: http://refactor.blog.com/2012/07/13/porting-javas-getparametermap-functionality-to-pure-javascript/
It converts request parameters to a json representation.
function getParameterMap () {
if (window.location.href.indexOf('?') === (-1)) {
return {};
}
var qparts = window.location.href.split('?')[1].split('&'),
qmap = {};
qparts.map(function (part) {
var kvPair = part.split('='),
key = decodeURIComponent(kvPair[0]),
value = kvPair[1];
//handle params that lack a value: e.g. &delayed=
qmap[key] = (!value) ? '' : decodeURIComponent(value);
});
return qmap;
}
Next, inside your success handler function:
success: function(json) {
//please really convert the server response to a json
//I don't see you instructing jQuery to do that yet!
//handleAs: 'json'
var qstring = '?';
for(key in json) {
qstring += '&' + key + '=' + json[key];
qstring = qstring.substr(1); //removing the first redundant &
}
var urlTarget = 'abc.html';
var urlTargetWithParams = urlTarget + qstring;
//will go to abc.html?key1=value1&key2=value2&key2=value2...
window.location.href = urlTargetWithParams;
}
On the next page, call getParameterMap.
var jsonRebuilt = getParameterMap();
//use jsonRebuilt
Hope this helps (some extra statements are there to make things very obvious). (And remember, this is most likely a wrong way of doing it, as people have pointed out).
Here is my post about communicating between two html pages, it is pure javascript and it uses cookies:
Javascript communication between browser tabs/windows
you could reuse the code there to send messages from one page to another.
The code uses polling to get the data, you could set the polling time for your needs.
You have two options I think.
1) Use cookies - But they have size limitations.
2) Use HTML5 web storage.
The next most secure, reliable and feasible way is to use server side code.