How to capture all requests with javascript? - javascript

I want to create a javascript interceptor in order to capture all requests that i see in the network tab and print them in the website.
Is that possible?
I have found the following code but it doesnt seem to work
let oldXHROpen = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
// do something with the method, url and etc.
console.log(url);
this.addEventListener('load', function() {
// do something with the response text
console.log('load: ' + this.responseText);
});
return oldXHROpen.apply(this, arguments);
}

Is that possible?
No.
have found the following code but it doesnt seem to work
That will only intercept requests made using the XMLHttpRequest object (not by anything else such as fetch, <script src="...">, <img src="..."> etc.).

Related

Laravel #include in js being immediatly executed

I am currently creating a feature on a webpage that aims to create an HTTP request to a server with js when a certain dropdown menu value is changed and the change the webpage based on the request response.
To accomplish this, I am using a Laravel #include to include the view that will build the page based on the json response.
The problem lies on this line allNews.innerHTML+=(`#include('partials.news.post',['news'=>`+news.data[i]+`])`)
The problem here is that an error (in the view caused by the argument news.data[i] being null) is immediately thrown by js when the page is loaded, it doesn't even wait for the EventListener to be triggered or for the request to be answered. If I delete this line of code it does not throw any error and works as expected, but if I comment it, the same error happens, which seems odd to say the least. What seems to be the problem here?
I used this stackoverflow question to base my development on.
I know the view is well built and does not throw errors because I use it in other instances.
<script defer>
let select = document.getElementById("sort-select");
let allNews = document.getElementById("posts-result");
let xhttp = new XMLHttpRequest();
console.log(js_query)
select.addEventListener("change",function(){
xhttp.open("GET", "/api/load-posts-search?sortBy="+ select.value +"&search=" + js_query, false);
xhttp.send();
let news = JSON.parse(xhttp.responseText);
console.log(news);
allNews.innerHTML=""
for(i=0;i<news.total;i++)
{
console.log(news.data[i]);
allNews.innerHTML+=(`#include('partials.news.post',['news'=>`+news.data[i]`])`)
}
})
</script>
The XMLHttpRequest will be asynchronous, so I think you need to change this:
select.addEventListener("change",function(){
xhttp.open("GET", "/api/load-posts-search?sortBy="+ select.value +"&search=" + js_query, false);
xhttp.send();
let news = JSON.parse(xhttp.responseText);
console.log(news);
allNews.innerHTML=""
for(i=0;i<news.total;i++)
{
console.log(news.data[i]);
allNews.innerHTML+=(`#include('partials.news.post',['news'=>`+news.data[i]`])`)
}
})
to:
select.addEventListener("change",function(){
xhttp.open("GET", "/api/load-posts-search?sortBy="+ select.value +"&search=" + js_query, false);
xhttp.send();
// wait on the response from the request
xhttp.onload = function() {
let news = JSON.parse(xhttp.responseText);
console.log(news);
allNews.innerHTML=""
for(i=0;i<news.total;i++)
{
console.log(news.data[i]);
allNews.innerHTML+=(`#include('partials.news.post',['news'=>`+news.data[i]`])`)
}
}
})
I'm not sure about using the #include within the JavaScript, it's not something I've done to know how well it would work. If the included blade file was static I think it would be fine, I'm just not sure how it would work passing it a dynamic news property that comes from an ajax request, i.e. one part of the #include is server side and one is client side, but I could be wrong and it will work completely fine.
You might need to refactor and return the html of the generated partial from the controller instead of trying to do it within the success stage of the ajax request.

Redirecting XMLHTTP request - Javascript

I have a web page that has a too much content and javascript. When the page loads it makes multiple requests using Ajax and XMLHttp to load data. Is there a way to hook up all these requests and direct them to a different server.
For example the webpage fetches data from www.apple.com/data and www.mango.com/data after it is loaded. Is is possible to insert a script somewhere in the webpage which automatically changes any request made to www.orange.com/data.
Waiting for answer. Thanks
You can add a global handler to the ajaxSend event, the event will be triggered right before the ajax request being sent out. So you can check the request uri, apply some filtering logic, and then redirect the request by abort the original and resend it.
Below is an example
$(document).ajaxSend(function(e, xhr, opt) {
if (opt.url.indexOf("www.apple.com") !== -1) {
// abort the request
xhr.abort();
// change the uri to www.orange.com
opt.url = opt.url.replace("www.apple.com", "www.orange.com");
$.ajax(opt);
}
});
Ok. So I followed Anthony C's answer and it did actually work. But the problem with his solution is that it only works with Ajax requests not XMLHttpRequests (I am not sure why, I am a beginner at this topic.) However digging on his idea of creating a hook I came across a similar post here How to get the URL of a xmlhttp request (AJAX). The code provided a way to fetch the requested URL for each request. So by a little tweak to the code I managed to come up with this:-
XMLHttpRequest.prototype.open = (function(open) {
return function(method,url,async) {
var uri=getLocation(url);// use get location function to convert requested url string into readable url
if(uri.hostname!="orange.com"){
url="https://orange.com" + url;
}
open.apply(this,arguments);
};
})(XMLHttpRequest.prototype.open);
var getLocation = function(href) {
var l = document.createElement("a");
l.href = href;
return l;
};
This code at top of the page allows me to change the host name of all XMLHttpRequests that are not directed towards orange.com. Though I am sure there are better ways to write this code as well but since I am not an expert over javascript this will suffice my need for the time.

Load json into javascript

So I have a json html link that like below
www.pretendJsonLink.com/getData
and the data i receive is below:
{"Items":[{"date":1498850140373,"displayId":"003","sentId":"121213",
"customer":"ME"}, {"date":1452870140571,"displayId":"007","sentId":"152713",
"customer":"YOU"}],"Count":2,"ScannedCount":2}
I need to load this into a js file so i can then call them as needed in a html file in an id="" tag
Like Items.date and Items.customer or something like it
Any help would be great and I understand that this should be a simple task, but i can also forward my search history as well :) i have been looking for solutions that work, but just cant seem to find anything that fits my needs
Use JSON.parse() function. Here is the link to documentation
You can use XMLHttpRequest . I found a gist that gives a good example and included it (simplified), below:
var req = new XMLHttpRequest();
req.open('GET', 'www.pretendJsonLink.com/getData');
req.onload = function() {
if (req.status == 200) {
// do what you want, here, with the req.response
// take a look at the object that gets returned, you may need
// to call JSON.parse(), etc.
console.log('success', req.response);
} else {
console.log('error', req.statusText);
}
};
// Handle network errors
req.onerror = function() {
console.log("Network Error");
};
// Make the request
req.send();

Append something always to an XHR Request

I want to attach a JS Variable to every XHR request that will be issued from my single page web application.
What would be the best approach to achieve this? I don't want to establish special methods for sending with this attributes, as there may be third parties integrating with my application.
I thought about overriding the send method on the XHR Object but thats not considered good style either.
I can't use cookies due to requests being cross-domain.
Any better idea or approach to this?
Thank you!
-Alessandro
if you really want to extend the existing functionalities without adding any library-like function, you could solve this using monkey patching:
(function() {
var originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
var getParameter = 'foo=bar';
if(url.indexOf('?') === -1) {
url = url + '?' + getParameter;
} else {
url = url + '&' + getParameter;
}
console.log('you just got monkey-patched! url is now:', url);
originalOpen.call(this, method, url, async, user, password);
}
})();
var request = new XMLHttpRequest();
request.open('get', 'http://google.com');
see also this jsfiddle for a working example.
you can use the same technique when injecting stuff into the body of a request if you patch the send() function.
if you do, ensure you take care for the type of the data to be transmitted (see MDN). it doesn't make sense to append a parameter to a binary body ;)

AJAX function that uses the POST method creates the following error. Error: returned status code 414 Request-URI Too Large

I'm using an AJAX function to transfer data to a PHP file. The data that I'm passing to the AJAX function is 17000 characters long. This is generally too long to transfer using the GET method, however one would think that the POST method would allow for such large variables to be be passed on.
Here's the AJAX function I'm using:
function ajaxFunction(id, datatypeString, pathToFileString, variable){
var myRequestObject = null;
document.getElementById(id).innerHTML = "<span>Started...</span>";
if (window.XMLHttpRequest)
{
myRequestObject = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
try
{
myRequestObject = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
myRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {}
}
}
myRequestObject.onreadystatechange = function()
{
document.getElementById(id).innerHTML = "<span>Wait server...</span>";
if(myRequestObject.readyState == 4)
{
if(myRequestObject.status == 200)
{
// process a document here
document.getElementById(id).innerHTML = "<span>Processing file...</span>"
if(datatypeString == "txt"){
//Injects code from a text file
document.getElementById(id).innerHTML = myRequestObject.responseText;
}
else if(datatypeString == "xml"){
//Injects code from an XML file
document.getElementById(id).innerHTML = myRequestObject.responseXML.documentElement.document.getElementsByTagName('title')[0].childNodes[0].nodeValue; // Inject the content into the div with the relevant id
}
else{
document.getElementById(id).innerHTML = "<span>Datatype exception occured</span>";
}
}
else
{
document.getElementById(id).innerHTML = "<span>Error: returned status code " + myRequestObject.status + " " + myRequestObject.statusText + "</span>";
}
}
};
myRequestObject.open("POST", pathToFileString+variable, true);
myRequestObject.send(null);
}
And this is the function call to that AJAX function:
ajaxFunction("myDiv", "txt", "processdata.php", "?data="+reallyLargeJavascriptVariable);
Also this is the error that I'm getting when the AJAX function is called:
Error: returned status code 414 Request-URI Too Large
I've looked around on Stackoverflow and other websites for a solution to this problem. However most answers come down to: "Use the POST method instead of the GET method to transfer the data."
However as you can see in the AJAX function, I'm already using the POST method.
So I'm not sure what's going on here and what to change in my code to solve this issue. I simply want to be able to pass very large variables to my function, but with this function that doesn't seem possible.
Given the error, the limitations of the URI seem to be causing the problem. However, I'm using the POST method and not the GET method, so why is the variable still passed via the URI? Since I am not using the GET method, but rather the POST method like many people suggested in other threads about this problem, I'm not sure why the URI is involved here and is seemingly causing a problem.
Apparently the URI is putting a limit on the size of the variable that I can transfer, however I'm using the POST method, so why is this error occurring and how can I adjust my AJAX function to make it work with the large variables that I want to transfer using AJAX?
When you're doing a POST you need to pass the POST data on the .send (you're currently passing null). You need to set a few header details, as well.
myRequestObject.open("POST", pathToFileString, true);
myRequestObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
myRequestObject.setRequestHeader("Content-length", variable.length);
myRequestObject.send(variable);
If you're currently passing a question mark in the start of variable or end of the path go ahead and remove it.

Categories

Resources