Say I have several JavaScript includes in a page:
<script type="text/javascript" src="/js/script0.js"></script>
<script type="text/javascript" src="/js/script1.js"></script>
<script type="text/javascript" src="/js/script2.js"></script>
<script type="text/javascript" src="/js/script3.js"></script>
<script type="text/javascript" src="/js/script4.js"></script>
Is there a way i can tell if any of those weren't found (404) without having to manually check each one? I guess i'm looking for an online tool or something similar. Any ideas?
If you get the Firebug firefox plugin and enable the consoles it should tell you when there are errors retrieving resources in the console.
I don't use other browsers enough to know where to find a similar feature in them, but Safari has an Activity window that displays all of the included files for a given web page and which ones were unable to be retrieved.
If you want to monitor on the fly without actually checking if it exists, then I suggest placing dynamic variables inside the files. Then just do something like this:
var script0Exists = true; // inside script0.js
var script1Exists = true; // inside script1.js
Then in your other files, just use:
if ( script0Exists ) {
// not a 404 - it exists
}
Log your 404's.
If you don't want to check it manually on the client you will need to do this server-side. You need to make sure whichever webserver you are using is configured to log 404s and then check that log to see which HTTP requests have failed.
If your webhost always returns the HTTP result "200 OK", whether the file exists or not (the latter should give a "404 Not Found"), the browser has no way of telling if it received a script or not.
You might try retrieving the files via XMLHttpRequest, examine the data, and if they look like JS, either eval() them, or create a script tag pointing to the exact same URL you downloaded (if the script is cacheable, it won't be transferred again, as the browser already has it).
Related
Heyo,
I'm trying to create a script that opens a URL and sign in using the given credentials.
Therefore I created this:
window.open("https://stackoverflow.com/users/login");
document.getElementById('email').value = "ThisIsMy#Email.com";
document.getElementById('password').value = "ThisIsMyPassword";
document.getElementById('submit-button').click();
But then I changed the code to wait for the page to load using window.onload:
window.open("https://stackoverflow.com/users/login");
window.onload = function() {
document.getElementById('email').value = "ThisIsMy#Email.com";
document.getElementById('password').value = "ThisIsMyPassword";
document.getElementById('submit-button').click();
}
However, this does not seem to work.
Therefore I added some console.log into my code to debug, like this:
console.log("starting")
window.open("https://stackoverflow.com/users/login");
console.log("page open")
window.onload = function() {
console.log("page loaded")
document.getElementById('email').value = "ThisIsMy#Email.com";
document.getElementById('password').value = "ThisIsMyPassword";
document.getElementById('submit-button').click();
console.log("signed in")
}
When I run the code in the console (Chrome/Firefox), I get back started and page open, but nothing else.
When I test the function isolated (i.e. the 3 different document.getElementById) it works just fine. Something must be wrong with the window.onload call?
From other sources here on StackOverflow I tried to use document.onload instead, and I also tried to use document.addEventListener('DOMContentLoaded', function() {...}, but none of these seems to be working either.
Does anyone have any suggestions?
#newbie
You simply can't access a cross origin page. What you are trying is only available to browser addons. And addons also require a specific permission granted by the user. For example the chrome permission to modify a webRequest: https://developer.chrome.com/docs/extensions/reference/webRequest/
window.open() returns the child window and this can be accessed IF it is about:blank or if the same-origin-rule applies (protocol, hostname and port - see pic below). Take a look at this fiddle it shows something similar to what you are trying. (CORS 1)
Here you can see which child windows you may have access to. This means modify it on the fly or override it's content/location completly.
The only method to communicate between two pages is: window.postMessage() and the window: Message-Event which provides an easy to use API for communication.
in your html page, in the script tag, where you call to your js page, add defer. like this:
<script src="your_script.js" defer></script>
I would like to remind you it is not a very good idea to use password credentials inside javascript since it is hard to protect from public appearance.
I believe you can solve this kind of problem with programs such as Python, C++ , maybe Java , but Javascript is a Client-Side program which has some limitations but if you ask me these limitations actually makes it quite fun to use most of the time.
I'm trying to set up a HikVision IP-based camera for some work I'm doing and it refuses to log in to the camera (the login button appears to do nothing).
The reason for this, when I break out the Chrome debugger console and investigate a bit deeper, is that the inbuilt login.js file (the one supplied by the camera) contains the code:
function document.onkeydown()
{
and the browser is complaining that the . is an invalid token in this context.
So my first question is simple: is this valid or invalid Javascript?
If it's invalid, I just have to track down the developer for a good talking to :-)
If it's valid, how do I get Chrome to stop complaining so that it can continue to process the rest of the file (including the definition of login function which is what would normally be called when I click on the login button)?
And, if it's not invalid and I don't want to wait around for a vendor fix, is it viable to just replace the login page and the Javascript file with local ones?
In other words, have those two files on my desktop (using 127.0.0.1) but have them reference all the other ones on the camera itself (192.0.0.whatever).
So, rather than accessing http://camera.com/page/login.asp which contains:
<script type="text/javascript" src="../script/login.js" />
<script type="text/javascript" src="../script/other.js" />
<script type="text/javascript" src="../script/again.js" />
I'd instead access file://login.htm, which would contain:
<script type="text/javascript" src="my_good_login.js" />
<script type="text/javascript" src="http://camera.com/script/other.js" />
<script type="text/javascript" src="http://camera.com/script/again.js" />
There is a problem with the firmware for some early HikVision cameras, in version 4.x.
The best solution is to upgrade the firmware to 5.2 where the Javascript code in the firmware is fixed.
This can be done with the SPD tool from HikVision itself.
However, if that's not an option, the scheme suggested should work. You just have to ensure that you correctly copy the errant firmware files off the camera onto your local box. That means:
Making an exact copy of the top-level page and errant login Javascript file locally (meaning on your host machine rather than the camera). This is probably as simple as just cut'n'pasting the browser source for both into new files(a).
Fixing the local copy of the errant login Javascript file, replacing document.onkeydown with the correct onkeydown.
Ensuring that you use the local top-level page from your browser rather than the on-camera one: this will ensure it uses the local login Javascript file.
Having that top-level page use your fixed login Javascript file: given it is a relative URL, that should work without change.
Ensuring the local top-level page accesses the other files on the camera: this will entail replacing the relative URLs with absolute ones.
(a) The only worrying possibility is the fact your current top-level page is an ASP one, whereas this process gets its HTML output fro creating the local top-level file. If the ASP file on the camera simply generates the same HTML each time, you'll be file.
However, if it's more complicated than that, you may have to do something tricky like extract the HTML from the camera each time with a script and massage it to change the URL accesses within a local page. Then access that local page from the browser. This could be automated but it's starting to get a little more difficult.
So, all in all, an upgrade to later fixed firmware is probably still the best option.
I have a Google +1 button on my site that requires the following script:
<script src="https://apis.google.com/js/platform.js" async defer></script>
The problem is as of today, apis.google.com can't be pinged from everywhere (servers are down) and some of my users don't see a button. I don't always want to use my own copy of the script because I can see that breaking the +1 functionality at some point. I'd like to use something like the solution from this question: my server's fallback copy should be fetched only when the CDN fails.
What's a good way to do that for this script? Is there a generic way to do this for any remote script using jQuery or plain js? Thanks in advance.
EDIT:
I tried jQuery getScript() and wrapped it in a function like this:
function fetch_script(script,fallback) {
$.getScript( script )
.fail(function() {
$.getScript( fallback );
});
};
This does not always work and is not reliable. Two problems I found:
500 errors trigger the fail method, but 404 errors do not and the fallback script is not loaded in these cases. Not sure what happens if the server is just down.
Some scripts are fetched (I see this in the console) but are somehow not executed (or they fail silently). Here's a script that doesn't work.
I am using head.js and using the below file to initiate the javascript file calls:
<script src="/scripts/load.js" type="text/javascript"></script>
In the load.js file I have the following code:
head.js(
{livechat: "/scripts/livechat.js"},
{jquery: "http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"},
{jquerytools: "http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js"},
{slider: "/scripts/jquery.nivo.slider.pack.js"},
{prettyphoto: "/scripts/jquery.prettyPhoto.js"},
{sliderfunctions: "/scripts/slidercode.js"},
{functions: "/scripts/functions.js"}
);
My problem is, even though I removed the livechat line, the chat box is still appearing on all my website pages unless I manually clear the browser cache. My concern is that I no longer utilize the livechat service and I do not want the visitors to be confused by seeing the livechat box appear but not function correctly.
Is there any way to tell head.js that there has been a change in the files being loaded and to refresh browser cache or something?
You could put something along the lines of this:
<script src="/scripts/load.js?date=123456789" type="text/javascript"></script>
Adding a query string to this file should trick the browser into thinking it's something it hasn't seen before.
Say I've got this script tag on my site (borrowed from SO).
<script type="text/javascript" async=""
src="http://edge.quantserve.com/quant.js"></script>
If edge.quantserve.com goes down or stops responding without returning a 404, won't SO have to wait for the timeout before the rest of the page loads? I'm thinking Chaos Monkey shows up and blasts a server that my site is depending on, a server that isn't part of a CDN and has a poor failover.
What's the industry standard way to handle this issue? I couldn't find a dupe on SO, maybe I'm searching for the wrong terms.
Update: I should have looked a bit more closely at the SO code, there's this at the bottom:
<script type="text/javascript">var _gaq=_gaq||[];_gaq.push(['_setAccount','UA-5620270-1']);
_gaq.push(['_setCustomVar', 2, 'accountid', '14882',2]);
_gaq.push(['_trackPageview']);
var _qevents = _qevents || [];
(function(){
var s=document.getElementsByTagName('script')[0];
var ga=document.createElement('script');
ga.type='text/javascript';
ga.async=true;
ga.src='http://www.google-analytics.com/ga.js';
s.parentNode.insertBefore(ga,s);
var sc=document.createElement('script');
sc.type='text/javascript';
sc.async=true;
sc.src='http://edge.quantserve.com/quant.js';
s.parentNode.insertBefore(sc,s);
})();
</script>
OK, so if the quant.js file fails to load, it's creating a script tag with ga.async=true;. Maybe that's the trick.
Possible answer: https://stackoverflow.com/a/1834129/30946
Generally, it's tricky to do it well and cross-browser.
Some proposals:
Move the script to the very bottom of the HTML page (so that almost everything is displayed before you request that script)
Move it to the bottom and wrap it in <script>document.write("<scr"+"ipt src='http://example.org/script.js'></scr"+"ipt>")</script> or the way you added after update (document.createElement('script'))
A last option is to load it via XHR (but this works only for same-domain, or cross-domain only if the CORS is enabled on a third-party server); you can then use timeout property of the XHR (for IE and Fx12+), and in the other browsers, use setTimeout and check the XHR's readyState. It's kind of convoluted and very non-cross-browser for now, so the option 2 looks the best.
Make a copy of the file on your server and use this. it will load your copy only if the one from the server has failed to load
<script src="http://edge.quantserve.com/quant.js"></script>
<script>window.quant || document.write('<script src="js/quant.js"><\/script>')</script>
To answer your question about the browser having to wait for the script to load before the rest of the page loads, the answer to that would typically be no. Typical browsers will have multiple threads processing the download of the page and linked content (CSS, images, js). So the rest of the page should be loaded, though the user's browser indicator will still show the page trying to load until the final request is fulfilled or timed out.
Depending on the nature of the resource you are trying to load, this will obviously effect your page differently. Typically, if you are worried about this, you can host all your files on a common CDN (or your website if it is not that highly trafficked), that way at least if one thing fails, chances are everything is failing and you have a bigger issue to contend with :)