I'm new to Javascript and am trying to write a userscript which tracks all Ajax calls made within a specific website and if the reponse status code is not 200, I want to automatically repeat that request.
Also these requests I want to repeat are all POST requests which probably makes it even harder.
I've come so far that I'm tracking all Ajax calls but since it seems to be impossible to capture the formdata sent from the POST requests, I don't know how I could repeat the failed calls.
(function() { // Overriding XMLHttpRequest
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener("readystatechange", function() {
console.log("an ajax request was made")
console.log(realXHR.status)
//If the status is not 200, repeat the request with same data etc
}, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
})();
You can try by calling the same function again
if(realXHR.status !==200){
newXHR();
}
Related
First of all I have to say that I have NO EXPERIENCE in Ajax and I just need this one explanation in order for me to create a simple chrome extension.
There is not much I could find on internet even tho I believe this is very simple.
I need a part of code where I would "call" url from website and I need to adjust certain arguments in that url.
Request URL:http://URL_OF_THE_WEBSITE/v1/send?token=TOKEN_VALUE
Request Method:POST
Request Payload :
{amount: 1, user_id: 12345678}
amount: 1
user_id: 12345678
(this is something I get from Network panel- with url and token changed to real things - while calling url automatically from website, but I need to be able to call it manually too.)
So I have an idea of mixing AJAX(which I don't know) and JS in order for me to call this url.
I would use variables for both TOKEN_VALUE and amount&user_id, but I don't know how to even call that url and how to set "request payload" in order for site to do the thing I want it to do.
I would really appreciate if someone would be kind enough to help :)
Work I have done, but doesn't work:
var request=new XMLHttpRequest;
request.open("POST","https://URL_OF_THE_WEBSITE/v1/send?token=TOKEN_VALUE"),request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"),request.Payload("user_id=12345678&amount=5");
I basically tried to remake an example I found online, but it didn't work out, therefore I need someone to actually explain to me how this works and how can I adjust arguments that I need.
function callAjax() {
// the XMLHttpRequest returns the ajax object that has several cool methods, so you store it in the request variable
// #data contains the $_POST[amount],$_POST[user_id],$_POST[whatever] since we are using POST method, if you're using PHP as a server side language
var request = new XMLHttpRequest(),
url = 'place_here_the_url_only',
data = 'amount=1&user_id=12345678&whatever=dataYouWantToSendToServerFromBrowser',
token = document.querySelector('meta[name="csrf-token"]').content;
// when the server is done and it came back with the data you can handle it here
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// do whatever you want!
console.log("The request and response was successful!");
}
};
// method post, your giving it the URL, true means asynchronous
request.open('POST', url, true);
// set the headers so that the server knows who is he talking to, I'm using laravel 5.5
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
// Token needed
request.setRequestHeader('X-CSRF-TOKEN', token);
// then you send the data and wait for the server to return the response
request.send(data);
}
Ajax: Asynchronous JavaScript And XML
It is a mean of communication between the browser and the server hosting the website, it cannot call any other server.
Asynchronous means the website continues to function normally, until the request is returned from the server and the:
if (this.readyState == 4 && this.status == 200) { }
gets triggered
I am trying to make api call to get spotify albums in native javascript without using any js frameworks. I am running into issues where I am unable to send Oauth token using native js. For spotify I have client id and client scret. I can either use that or the Oa
(function() {
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.spotify.com/v1/albums", false);
xhr.send();
document.getElementById("results").innerHTML = xhr.responseText;
})();
function request(callback) {
var xobj = new XMLHttpRequest();
// true parameter denotes asynchronous
xobj.open('GET', YOUR_URL_HERE, true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
// This marks that the response has been successfully retrieved from the server
// Utilize callback
callback(xobj.responseText);
}
};
xobj.send(null);
}
I would definitely recommend taking a look at the link Frobber provided. It's always better to understand why something does/doesn't work rather than just getting it to work. Here is a mock request to get you started. Hope this helps!
I think you need to read a basic tutorial on how to use XMLHttpRequest, which you can find here
One immediate problem with your code is that it's not using any callback to read the result that comes back from the server. This is all happening asynchronously, so what's occurring in your case is that you're send()ing the request, and then immediately setting innerHTML to a value that probably isn't even available from the server yet.
Check the tutorial for how to get that information back from the server when it's ready.
Note the use of the myFunction callback, and note the use of onreadystatechange. What's happening here is that send() is sending something to the server, in a separate execution thread. You need to register a callback function that will perform the data fetching and DOM update when the server reports back that the data is available, not immediately.
I am attempting to create a chrome extension that queries an external source as a reference to block or allow through a particular page. The following is part of my code. I am new to javascript, and scope always seems to be something that screws me up.
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
var http = new XMLHttpRequest();
var url = "http://xxx.xx.xxxx";
var params = "urlCheck="+encodeString_(details.url);
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
guilt = 0;
console.log(guilt);
}else if(http.readyState == 4 && http.status == 404){
guilt = 1;
console.log(guilt);
}
}
http.send(params);
if(guilt == 1){
return {cancel: true};
}else{
return {cancel: false};
}
},
{urls: ["<all_urls>"],
types:["main_frame"]
},
["blocking"]
);
Any help would be greatly appreciated! Thanks.
You can't do that.
Your code does not work as expected because XHR is asynchronous; your onreadystatechange is executed after the whole outer function finishes. So guilt will be undefined or, worse, stale (from the last request).
For more information, see this canonical question: Why is my variable unaltered after I modify it inside of a function?
However, if you try to fix this, you'll notice that you can't return a response from within the async handler.
This is intentional: there is no function to pass and then call later (like sendResponse in Messaging API), because Chrome will not wait for you. You are expected to respond to a blocking call in a deterministic and fast way.
If the optional opt_extraInfoSpec array contains the string 'blocking' (only allowed for specific events), the callback function is handled synchronously. That means that the request is blocked until the callback function returns.
You could try to bypass it by using synchronous XHR calls. That is not a very good idea in general, since loading a remote response takes a long time, and synchronous XHR is considered deprecated. Even though you limited your queries to "main_frame" requests, this still adds an uncertain delay to each load.
A proper way to do that would be to load a set of rules from a server and update it periodically, and when a request occurs validate it against this local copy of rules. This is the approach extensions like AdBlock use.
In my web application, what the user does on the page have to be sent my database, so I have the latest changes saved.
I just call the function with the request here when the user close the page:
window.onbeforeunload = sendData;
But where the problems come up is when I send data every 10 second. I do send my requests sync and not async (or it would not be sent onbeforeunload). The problem is that this adds delays to the user interface when the data is sent every 10 second.
setInterval(sendData,10000);
This is what's getting called:
function sendData(){
var xhr = new XMLHttpRequest();
var localData = datatodatabase;
xhr.open("POST", "handler.php", false);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("pack="+datatodatabase);
}
Is it possible to add this inside a Web Worker to make the synchronized requests stop delaying what everything else is going on?
(As I said: I have to use synchronized because of onbeforeunload)
Why don't you make it asynchronous every 10 seconds, but onbeforeunload make it synchronous? Like this:
setInterval(function () {
sendData(true);
}, 10000);
window.onbeforeunload = function () {
sendData(false);
}
function sendData(async) {
// Make the ajax call the specific way based on whether *async* is *true* or *false*
// Probably eventually:
xhr.open("POST", "handler.php", async);
}
Is it possible to create a Javascript and include it in a web page that the function of this JS is to "catch" all GET request or any other Ajax calls made from any other Javascript on the page? Either to log it or just plain show it in a Alert box.
The "other Javacript" that will be executing GET or Ajax calls is arbitrary. I mean I have no control over that in terms of what it is.
And once caught I need to check which Javascript executing which GET or Ajax calls.
Is this possible?
Try this snippet. It extends the send function so that you can execute something before or after the real sending.
XMLHttpRequest.prototype.reallySend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(body) {
// Do something...
this.reallySend(body);
};
var req = new XMLHttpRequest();
req.open("GET", "any.html", true);
req.send(null);
const nativeOpen = XMLHttpRequest.prototype.open;
const proxiedOpen = function () {
if (arguments[1].includes('youUrl.com')) {
// do some ...
}
nativeOpen.apply(this, arguments);
};
Refer to the answer:
Intercept AND CHANGE the results of an ajax call