I want to check, if a website is reachable with XMLHttpRequest.
I wrote a JS-function: UrlExsists(url); to try and establish a connection.
function UrlExists(url) {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
if (http.status != 404) {
console.log("did work:" + url)
} else {
console.log("did not work:" + url)
}
};
When i go to my browser console and call the function like so:UrlExsists("https://www.google.com/");, the following is displayed in the console:
"XHR HEAD https://www.google.com/ [HTTP/2.0 200 OK 668ms]"
But It fails due to "Cross-Origin Request Blocked" and a Network Error occurs. = >img as reference
If I call UrlExsists("https://www.google.com/test"); the following is displayed:
"XHR HEAD https://www.google.com/test [HTTP/2.0 404 Not Found 0ms]"
And again "Cross-Origin Request Blocked" and Network Error. = > img as reference
Now these Status codes 404 and 200 are exactly, what i want, but how do i get these in javascript, to determine if the given website is available?
And if I'm on the wrong track, can someone maybe nod me to the right one?
I think, I found a solution for my problem.
The fetch API seems to do just what I want.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
I did as the accepted answer from Kaiido instructed:
Check if online resource is reachable with JavaScript, not requiring the The Same Origin Policy to allow it
It is not possible due to the CORS error (you have no right to load other site's script, if it is not enable with Cross-Origin Resource Sharing: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). You just cant get the information, not even the HTTP response code.
The only workaround I see is append to the DOM a css request. And checking if the css successfully loaded. But its not a general solution, you need to pick some css class and check if it is loaded. And also you need to disable the cache with HTML meta tags.
You also can append css link tag dynamically (description: https://gist.github.com/chrisyip/1403858)
<link rel="stylesheet" type="text/css" href='https://mysite/custom.css'>
In the cusom css you need some unique class like:
.url-exists {
}
And after some delay (like 3-5 seconds timeout), you check if the css is successfully loaded:
function verifyStyle(selector) {
var rules;
var haveRule = false;
if (typeof document.styleSheets != "undefined") { //is this supported
var cssSheets = document.styleSheets;
outerloop:
for (var i = 0; i < cssSheets.length; i++) {
//using IE or FireFox/Standards Compliant
rules = (typeof cssSheets[i].cssRules != "undefined") ? cssSheets[i].cssRules : cssSheets[i].rules;
for (var j = 0; j < rules.length; j++) {
if (rules[j].selectorText == selector) {
haveRule = true;
break outerloop;
}
}//innerloop
}//outer loop
}//endif
return haveRule;
}//eof
var ok = verifyStyle(".url-exists");
If the variable ok is true then the given url (https://mysite/) is accessible.
Related
I have a strange problem.
Sometimes error 404 appears. But not always and thats the strange part..
I made a page with javaScript and at the end of the page iam changing images with this java script function
var backGround = ['img/wall1.jpg', 'img/wall2.jpg', 'img/wall3.jpg'];
var header = document.getElementById('headerBlanco');
var i = 0;
setInterval(function(){
if(i !== backGround.length - 1){
i++;
}else{
i = 0;
}
header.style.backgroundImage = 'url(' + backGround[i] + ')';
}, 6000);
It works like i wanted but sometimes the browser cant find a image and error 404 appears..
Failed to load resource: the server responded with a status of 404 (Not Found)
can somebody explain me why this can happen?
This is the site where you can see it.
You need to click on the buttons to see it happen.
http://www.leerappel.nl
The error you have mentioned in your comment is caused by header being null. This means that document.getElementById('headerBlanco') yields null. That means that headerBlanco does not necessarily exist. Make sure that the element exists and your url is correct. Also, instead of
if(i !== backGround.length - 1){
i++;
}else{
i = 0;
}
you can do this:
i = (i + 1) % backGround.length;
EDIT:
It turns out I misunderstood the situation. I mistakenly believed that the first comment of the question was made by the author. Since the item has a value, the 404 can most probably be attributed to internet connection problems.
I have an HTML page where several JavaScript, CSS and images files are referenced. These references are dynamically injected and user can manually copy the HTML page and the support files to another machine.
If some JS or CSS are missing, the browser complains in the console. For example:
Error GET file:///E:/SSC_Temp/html_005/temp/Support/jquery.js
I need somehow these errors reported back to me on the inline JavaScript of the HTML page so I can ask user to first verify that support files are copied correctly.
There's the window.onerror event which just inform me that there's a JS error on the page such as an Unexpected Syntax error, but this doesn't fire in the event of a 404 Not Found error. I want to check for this condition in case of any resource type, including CSS, JS, and images.
I do not like to use jQuery AJAX to verify that file physically exists - the I/O overhead is expensive for every page load.
The error report has to contain the name of the file missing so I can check if the file is core or optional.
Any Ideas?
To capture all error events on the page, you can use addEventListener with the useCapture argument set to true. The reason window.onerror will not do this is because it uses the bubble event phase, and the error events you want to capture do not bubble.
If you add the following script to your HTML before you load any external content, you should be able to capture all the error events, even when loading offline.
<script type="text/javascript">
window.addEventListener('error', function(e) {
console.log(e);
}, true);
</script>
You can access the element that caused the error through e.target. For example, if you want to know what file did not load on an img tag, you can use e.target.src to get the URL that failed to load.
NOTE: This technically will not detect the error code, it detects if the image failed to load, as it technically behaves the same regardless of the status code. Depending on your setup this would probably be enough, but for example if a 404 is returned with a valid image it will not trigger an error event.
you can use the onload and onerror attributes to detect the error
for example upon loading the following html it gives alert error1 and error2 you can call your own function e.g onerror(logError(this);) and record them in an Array and once the page is fully loaded post is with single Ajax call.
<html>
<head>
<script src="file:///SSC_Temp/html_005/temp/Support/jquery.js" onerror="alert('error1');" onload="alert('load');" type="text/javascript" ></script>
</head>
<body>
<script src="file:///SSC_Temp/html_005/temp/Support/jquery.js" onerror="alert('error2');" onload="alert('load');" type="text/javascript" ></script>
</body>
</html>
I've put together the code below in pure JavaScript, tested, and it works.
All the source code (html, css, and Javascript) + images and example font is here: on github.
The first code block is an object with methods for specific file extensions: html and css.
The second is explained below, but here is a short description.
It does the following:
the function check_file takes 2 arguments: a string path and a callback function.
gets the contents of given path
gets the file extension (ext) of the given path
calls the srcFrom [ext] object method that returns an array of relative paths that was referenced in the string context by src, href, etc.
makes a synchronous call to each of these paths in the paths array
halts on error, and returns the HTTP error message and the path that had a problem, so you can use it for other issues as well, like 403 (forbidden), etc.
For convenience, it resolves to relative path names and does not care about which protocol is used (http or https, either is fine).
It also cleans up the DOM after parsing the CSS.
var srcFrom = // object
{
html:function(str)
{
var prs = new DOMParser();
var obj = prs.parseFromString(str, 'text/html');
var rsl = [], nds;
['data', 'href', 'src'].forEach(function(atr)
{
nds = [].slice.call(obj.querySelectorAll('['+atr+']'));
nds.forEach(function(nde)
{ rsl[rsl.length] = nde.getAttribute(atr); });
});
return rsl;
},
css:function(str)
{
var css = document.createElement('style');
var rsl = [], nds, tmp;
css.id = 'cssTest';
css.innerHTML = str;
document.head.appendChild(css);
css = [].slice.call(document.styleSheets);
for (var idx in css)
{
if (css[idx].ownerNode.id == 'cssTest')
{
[].slice.call(css[idx].cssRules).forEach(function(ssn)
{
['src', 'backgroundImage'].forEach(function(pty)
{
if (ssn.style[pty].length > 0)
{
tmp = ssn.style[pty].slice(4, -1);
tmp = tmp.split(window.location.pathname).join('');
tmp = tmp.split(window.location.origin).join('');
tmp = ((tmp[0] == '/') ? tmp.substr(1) : tmp);
rsl[rsl.length] = tmp;
}
});
});
break;
}
}
css = document.getElementById('cssTest');
css.parentNode.removeChild(css);
return rsl;
}
};
And here is the function that gets the file contents and calls the above object method according to the file extension:
function check_file(url, cbf)
{
var xhr = new XMLHttpRequest();
var uri = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function()
{
var ext = url.split('.').pop();
var lst = srcFrom[ext](this.response);
var rsl = [null, null], nds;
var Break = {};
try
{
lst.forEach(function(tgt)
{
uri.open('GET', tgt, false);
uri.send(null);
if (uri.statusText != 'OK')
{
rsl = [uri.statusText, tgt];
throw Break;
}
});
}
catch(e){}
cbf(rsl[0], rsl[1]);
};
xhr.send(null);
}
To use it, simply call it like this:
var uri = 'htm/stuff.html'; // html example
check_file(uri, function(err, pth)
{
if (err)
{ document.write('Aw Snap! "'+pth+'" is missing !'); }
});
Please feel free to comment and edit as you wish, i did this is a hurry, so it may not be so pretty :)
#alexander-omara gave the solution.
You can even add it in many files but the window handler can/should be added once.
I use the singleton pattern to achieve this:
some_global_object = {
error: (function(){
var activate = false;
return function(enable){
if(!activate){
activate = true;
window.addEventListener('error', function(e){
// maybe extra code here...
// if(e.target.custom_property)
// ...
}, true);
}
return activate;
};
}());
Now, from any context call it as many times you want as the handler is attached only once:
some_global_object.error();
I am a beginner in both Ajax and MongoDB. I was hoping to visualize some of the data in my MongoDB using a web browser (which, for the moment, is running on the same host). For this, I thought it might be possible to get the data using XMLHttpRequests. I am running MongoDB with the --rest option and I checked that when I load hxxp://localhost:28017/test_db/ss_test/
on Firefox, I get the proper reply (a JSON document with the data in the ss_test collection of the test_db database). So far, so good.
I then wrote the following JavaScript function which I connected to the "onclick" of a button:
function makeRequest()
{
var myrequest = new XMLHttpRequest();
myrequest.onreadystatechange = function()
{
alert("status=" + myrequest.status + " readyState=" + myrequest.readyState)
if (myrequest.status == 200 && myrequest.readyState == 4)
{
// ...do something with the response
}
}
myrequest.open("GET", "http://localhost:28017/test_db/ss_test/", true);
myrequest.send();
}
So, when I load the html file on Firefox, open the console and click on my button, I see that the http request is indeed made, the status code is "HTTP/1.0 200 OK" and a response with Content-Length: 219257 is delivered, which looks great. However, the XMLHttpRequest object does not report the status=200. The alerts that pop up report a constant status of 0 as the readyState progressively becomes 1, 2 and 4 and my if statement is never true.
Could anyone please tell me what I am doing wrong? In the beginning I thought it was because my html was loaded on the browser by the file protocol or that I was seeing some same-origin policy related issue, but then I put the html file on a web server on localhost and loaded it from there and nothing changed. Thank you very much for any replies!
you need to create a function to handle the request.
http://www.ibm.com/developerworks/web/library/wa-ajaxintro2/
http://www.ibm.com/developerworks/library/wa-ajaxintro3/
function makeRequest()
{
var myrequest = new XMLHttpRequest();
myrequest.onreadystatechange = create_this_function()
{
}
myrequest.open("GET", "http://localhost:28017/test_db/ss_test/", true);
myrequest.send();
}
#
function create_this_function()
{
alert("status=" + myrequest.status + " readyState=" + myrequest.readyState)
if (myrequest.status == 200 && myrequest.readyState == 4)
{
// ...do something with the response
}
}
I added variables in the request as per the Microsoft standard below, var openRetVal and var sendRetVal... Odd thing is, that they dont get anything returned in them, so did Microsoft lie in their own documentation?
I was working on a ajax request, and like usual, IE is a difficult specimen to work with. I found that instead of doing a AJAX request, i can do an XDR. My code in chrome works, so i know the destination server is working and on a successful request does what is suppose to happen. Below is my code segment for an XDR.
if ($.browser.msie && window.XDomainRequest) {
var xdr = new XDomainRequest();
//var webstring = location.protocol +"//"+ location.host +"/" + WEBSERVICE_URL + "/test";
//WEBSERVICE_URL = "webservices/FormDesigner.svc";
var webstring = WEBSERVICE_URL + "/test";
var openRetVal = xdr.open("GET", webstring); //added this var as it supposidly gets a return value from the function call.
xdr.onload = function () {
var JSON = $.parseJSON(xdr.responseText);
if (JSON == null || typeof (JSON) == 'undefined') {
JSON = $.parseJSON(data.firstChild.textContent);
}
//below is my onsuccess call which is called by both successes for IE and NON-IE processes allowing all stuff to be piped into 1 call.
ajax_success(JSON);
};
xdr.ontimeout = function () {
alert("XDR Error. Timeout");
}
xdr.onerror = function () {
alert("XDR Error. Unable to do a Cross Domain Server Request.");
};
var sentRetVal = xdr.send(); //added this var as the function is suppose to return success or error as per microsoft.
}
It always returns onerror which is NOT what i am aiming for, naturally. I am pinging something within the same domain for the moment for testing purposes which is why there is not other stuff. Like i said, it works with other browsers so far... Is there an improper formatting I am unaware of? There is no data submitted as well with this test request.
If you are already using jQuery, just use jQuery for ALL BROWSERS, then you should not have any issues in IE.
<html>
<body>
<script type="text/javascript">
var req = new XMLHttpRequest();
req.open('GET', 'file://localhost/C:/Users/johan/mainMenu_2.html', false);
req.send(null);
if(req.status == 200)
dump(req.responseText);
var pageLinks = [];
var anchors = req.getElementsByTagName('a');
var numAnchors = anchors.length;
for(var i = 0; i < numAnchors; i++) {
//pageLinks.push(anchors[i].href);
document.write(anchors[i]);
}
</script>
</body>
</html>
With the access denied error on the 'GET' command
But I heard that you could get around this 'acces denied' error if you create an iframe and then read from that page. So how would you do this whitout using any server side languages?
file://localhost/C:/ is most definitely wrong.
Either use http://localhost or file://C:/
If possible, use a local web server because access to file:// URLs is riddled with restrictions in most browsers.
You can also, use relative path to the current page (without the domain name) to make a request. If this is going to be hosted in two different domains, then browsers would not allow you to do what you are doing, due to security restriction.
If you would like to perform from cross domain communication, you can follow Secure Cross-Domain Communication in the Browser.