URL validation/connectivity using javascript - javascript

I want to verify if an external url valid/exists/responsive using javascript. For example, "www.google.com" should return true and "www.google123.com" should return false.
I thought to use AJAX for this purpose by testing : if (xmlhttp.readyState == 4 && xmlhttp.status == 200) but it seems that this doesn't work for remote servers(external urls). As my server uses a proxy, i planned to use browser side script so that it automatically uses user's browser proxy if present.
Please tell me do I have to use "AJAX Cross Domain"? How to achieve this, as i simply want to validate a url.
Any way other than using AJAX?

I'm pretty sure this is not possible. Any AJAX that allowed you to call a random page on another domain in the user's context would open up all sorts or security holes.
You will have to use a server-side solution.

The usual way to avoid cross-domain issues is to inject a tag. Tags like image or script kan load their content from any domain. You could inject, say a script tag with type "text/x-unknown" or something, and listen to the tags load-event. When the load event triggers, you can remove the script tag from the page again.
Of course, if the files you are looking for happens to be images, then you could new Image() instead. That way you don't have to pollute the page by injecting tags, because images load when they are created (this can be used to preload images). Again, just wait for the load event on the image.
UPDATE
Okay, it seems I am jumping to conclusions here. There is some differences between browsers on how this can be supported. The following is a complete example, of how to use the script tag for validating urls in IE9 and recent versions of Firefox, Chrome and Safari.
It does not work in older versions of IE (IE8 at least) because apparently they don't provide load/error events for script-tags.
Firefox refuses to load anything if the contenttype for the script-tag is not empty or set to 'text/javascript'. This means that it may be somewhat dangerous to use this approach to check for scriptfiles. It seems like the script tag is deleted before any code is executed in my tests, but I don't for sure...
Anyways, here is the code:
<!doctype html>
<html>
<head>
<script>
function checkResource(url, callback) {
var tag = document.createElement('script');
tag.src = url;
//tag.type = 'application/x-unknown';
tag.async = true;
tag.onload = function (e) {
document.getElementsByTagName('head')[0].removeChild(tag);
callback(url, true);
}
tag.onerror = function (e) {
document.getElementsByTagName('head')[0].removeChild(tag);
callback(url, false);
}
document.getElementsByTagName('head')[0].appendChild(tag);
}
</script>
</head>
<body>
<h1>Testing something</h1>
<p>Here is some text. Something. Something else.</p>
<script>
checkResource("http://google.com", function (url, state) { alert(url + ' - ' + state) });
checkResource("http://www.google.com/this-does-not-exists", function (url, state) { alert(url + ' - ' + state) });
checkResource("www.asdaweltiukljlkjlkjlkjlwew.com/does-not-exists", function (url, state) { alert(url + ' - ' + state) });
</script>
</body>
</html>

Related

Is using XMLHttpRequest() an outdated way to make an Ajax call?

I'm simply using an example from a book I'm reading. The example is labeled, "Loading HTML with Ajax." This is the JS portion of the code:
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if(xhr.status === 200) {
document.getElementById('content').innerHTML = xhr.responseText;
}
};
xhr.open('GET', 'data/data.html', true);
xhr.send(null);
I'm getting the CSS portion of the code (headers, etc.) when I load the page onto the browser but none of the JS (there should be maps which would load onto the page). The example says I should comment out this portion of the code above:
xhr.onload = function() {
if(xhr.status === 200) {
document.getElementById('content').innerHTML = xhr.responseText;
...if I'm running the code locally without a server but that's not working, either.
Is using XMLHttpRequest() an outdated way to make an Ajax call?
Yes, but it still works and that's not the problem. The more modern way is fetch.
I'm getting the CSS portion of the code (headers, etc.) when I load the page onto the browser but none of the JS (there should be maps which would load onto the page).
That's because assigning HTML that contains script tags to innerHTML doesn't run the script defined by those tags. The script tags are effectively ignored.
To run those scripts, you'll need to find them in the result and then recreate them, something along these lines:
var content = document.getElementById('content');
content.innerHTML = xhr.responseText;
content.querySelectorAll("script").forEach(function(script) {
var newScript = document.createElement("script");
newScript.type = script.type;
if (script.src) {
newScript.src = script.src;
} else {
newScript.textContent = script.textContent;
}
document.body.appendChild(newScript);
});
Note that this is not the same as loading the page with script elements in it directly. The code within script tags without async or defer or type="module" is executed immediately when the closing script tag is encountered when loading a page directly (so that the loaded script can use document.write to output to the HTML stream; this is very mid 1990s). Whereas in the above, they're run afterward.
Note that on older browsers, querySelectorAll's NodeList may not have forEach, that was added just a few years ago. See my answer here if you need to polyfill it.
Because I didn't completely understand T.J.'s answer (no offense, T.J.), I wanted to provide a simple answer for anyone who might be reading this. I only recently found this answer on Mozilla.org: How do you set up a local testing server? (https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server). I won't go into details, I'll just leave the answer up to Mozilla. (Scroll down the page to the section titled, "Running a simple local HTTP server.")

could not connect to extensions after I document.write my webpage

I found questions regarding "extension not able to connect in new tab",where the solution is to use chrome.tab module, but din't found anything like this:
I am stuck at this from many days, I will be glad if anyone could help me around.
I am using extensions for cross Domain calls, but my webpage can connect to the extension (I think content script) only when my page is a pure html page.If I change my page's content using:
document.open();
document.write(html);
document.close();
(I did this keep the url of my webpage same when a user log in)
I cannot get any Response from extension.
Is there any solution which I am missing.
code for Reference:
HTML where I replace page:
PageLoader.prototype.loadHTML = function(html) {
if (history.pushState)
try {window.history.pushState(null, null, document.URL);}
catch (e) {};
document.open();
document.write(html);
document.close();
};
crossDomain Code:
this is function which is called on click of some button
`window.addEventListener( "message", function(event) {
if (event.source != window ) return;
callback(event.data.text);
});
window.postMessage( { type: "com_logincat_xhr_get", url: url }, "*");
`
This postMessage is done but did not get any response from chrome extension's content_script.js (only If I have used document.write in my webpage to replace the content).
content_script.js also contain eventListner for message.
window.addEventListener( "message", function(event)
{
/* It contains piece of code to send message (chrome.runtime.sendmessage) */
};
I found at some places content_script.js attaches only at pageLoad and document.write might be replacing things, but I did not found any solution for this.
I think the code is correct as it works smoothly when page is a simple direct html.I don't know what wrong document.write do to my webpage
I Hope It will help,
Thanks for the help.
Hey this is my solution to the above problem.
I found that content_script.js of Extensions attaches to DOM only at pageLoad.
and using document.write('html')
I was modifying the DOM, which was creating Issue for the connection with content_script.js,
so I decided to use
document.documentElement.innerHTML = html;
using this I got into another problem which was that scripts were not getting executed which were in var html.
for that I did this:
var scriptToInclude = document.getElementsByTagName('script');
for (var n = 0; n < scriptToInclude.length; n++)
eval(scriptToInclude[n].innerHTML);
and it worked :)

jquery load() equivalent for offline use

I am looking for an equivalent to jquery's load() method that will work offline. I know from jquery's documentation that it only works on a server. I have some files from which I need to call the html found inside a particular <div> in those files. I simply want to take the entire site and put it on a computer without an internet connection, and have that portion of the site (the load() portion) function just as if it was connected to the internet. Thanks.
Edit: BTW, it doesn't have to be js; it can be any language that will work.
Edit2:
My sample code (just in case there are syntax errors I am missing; this is for the files in the same directory):
function clickMe() {
var book = document.getElementById("book").value;
var chapter = document.getElementById("chapter").value;
var myFile = "'" + book + chapter + ".html'";
$('#text').load(myFile + '#source')
}
You can't achieve load() over the file protocol, no other ajax request is going to work for html files. I have tried even with the crossDomain and isLocale option on without anything success, even if precising the protocol.
The problem is that even if jQuery is trying the browser will stop the request for security issues (well most browsers as the snippet below works in FF) as it allows you to load locale file so you could get access to a lot of things.
The one thing you could load locally is javascript files, but that probably means changing a lot of the application/website architecture.
Only works in FF
$.ajax({
url: 'test.html',
type: 'GET',
dataType: 'text',
isLocale: true,
success: function(data) {
document.body.innerHTML = data;
}
});
What FF does well is that it detect that the file requesting local files is on the file protocol too when other don't. I am not sure if it has restriction over the type of files you can request.
You can still use the JQuery load function in this context:
You would could add an OfflineContent div on your page:
<div id="OfflineContent">
</div>
And then click a button which calls:
$('#OfflineContent').load('OfflinePage.html #contentToLoad');
Button code:
$("#btnLoadContent").click(function() {
$('#OfflineContent').load('OfflinePage.html #contentToLoad');
});
In the OfflinePage.html you could have to have another section called contentToLoad which would display on the initial page.

Avoid jQuery Mobile to force script/CSS reload using _=TIMESTAMP query string parameter

As far as I know, if you want to load JavaScript or CSS files together with a specific page that is automatically loaded via ajax then you have to put the CSS/JavaScript references within the <div data-role="page"> container.
Example:
<div data-role="page" data-theme="e">
<script type="text/javascript" src="/js/jquery/plugins/plugins.js"></script>
In general, this works fine. However, somewhere along the way, the script url gets modified:
/js/some_sepcial_script.js becomes e.g. js/some_sepcial_script.js?_=1299308309681
Where 1299308309681 is the current Unix timestamp which changes on every request and thus prevents caching. I am pretty sure that this is intended behaviour but does anyone know how you can prevent the timestamp from being appended to the script/CSS urls if you want to make the file cacheable?
Have you tried:?
$.ajax ({
// Disable caching of AJAX response */
cache: false
});
It should globally change ajax requests. I'm just not sure about external scripts.
[EDIT]
This is the source code involved for jquery mobile 1.0a3:
var all = $("<div></div>");
//workaround to allow scripts to execute when included in page divs
all.get(0).innerHTML = html;
to = all.find('[data-role="page"], [data-role="dialog"]').first();
//rewrite src and href attrs to use a base url
if( !$.support.dynamicBaseTag ){
var newPath = path.get( fileUrl );
to.find('[src],link[href]').each(function(){
var thisAttr = $(this).is('[href]') ? 'href' : 'src',
thisUrl = $(this).attr(thisAttr);
//if full path exists and is same, chop it - helps IE out
thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' );
if( !/^(\w+:|#|\/)/.test(thisUrl) ){
$(this).attr(thisAttr, newPath + thisUrl);
}
});
}
Nothing on there adds a cache preventing param.
[EDIT 2]
I know this goes beyond troubleshooting to a work around but have you tried dynamically loading the js like explained here: http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
(I know it can be done through jQuery but for testing purposes I'm trying to avoid jQuery)
if I include jQuery 1.4.3 instead of 1.5 everything works fine. That's a sufficient solution for me. Thanks again for your support.
Try running:
$.ajaxPrefilter("script", function (s) {
if (s.cache === undefined) {
s.cache = true;
}
});
Does it change this behavior?

IE6 does not parse the loaded JavaScript file (Recaptcha hosted by Google)

This is a really strange issue, I am trying to use the Recaptcha on one of the website, and it works for all browsers tested except for IE6.
I have made a reference to the google's js:
http://www.google.com/recaptcha/api/challenge?k=the_key
and it is loaded according to fiddler2 & the 'onreadystatechange' event (which have a readystate == 'loaded')
The normal work flow should be the loaded JS been parsed, and another js been requested, then the image loaded from google. my problem is that the first loaded JS file (content similar to below):
var RecaptchaState = {
site : 'xxxxxxxxxxxx',
challenge : 'xxxxxxxxxxxxxxxxxxxxxxxxx',
is_incorrect : false,
programming_error : '',
error_message : '',
server : 'http://www.google.com/recaptcha/api/',
timeout : 18000
};
document.write('<scr'+'ipt type="text/javascript" s'+'rc="' + RecaptchaState.server + 'js/recaptcha.js"></scr'+'ipt>');
is not parsed. First, the following JS test:
typeof RecaptchaState == 'undefined'
Secondly, there is no second script request (according to fiddler2), not to say the recaptcha image...
The script tag is put inside the body, after the recaptcha markups, and I have even tried to load the JS dynamically:
function GetJavaScript(url, callback) {
var script = document.createElement('script');
script.src = url;
var head = document.getElementsByTagName('head')[0];
var done = false;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function () {
if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
done = true;
callback();
// remove the hanlder
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
which gives same behaviour... what confuses me most is:
this issue occurs occasionally only when the page is redirectly from another page. (open the url directly in new browser window or refresh the page always works fine, however refresh page using JavaScript does not work...)
Please help, any advice and/or idea would be appreciated...
Double check that your script's src in the page source isn't api.recaptcha.net (some libraries use that, I know the Java one I was using did). If it is, that gets forwarded to www.google.com/recaptcha/api, and that seems to cause issues with IE6. Once I switched to using www.google.com/recaptcha/api as the actual script src, IE6 was completely happy. Good luck!
I solved this problem by using the https call, as per this thread in reCaptcha's Google Group.
This is not a solve, just an workaround.
Request the first js file: http://www.google.com/recaptcha/api/challenge?k=the_key
on the server site, and inject the first part of the script on the page directly:
var RecaptchaState = {
site : 'xxxxxxxxxxxx',
challenge : 'xxxxxxxxxxxxxxxxxxxxxxxxx',
is_incorrect : false,
programming_error : '',
error_message : '',
server : 'http://www.google.com/recaptcha/api/',
timeout : 18000
};
Then, using the GetJavaScript function and/or JQuery.getScript() function to load the second script:
http://www.google.com/recaptcha/api/js/recaptcha.js
This solution works for IE6 based on my test, and to make the server less load, I detect the user's browser at server end as well as client end to inject different logic.
I know this is dirty workaround, just in case this might help someone.
NOT ANSWER (or is it?):fo_Ok ie6. Seriously, forget it. Without this attitude ie6 will live forever. It is like ancient evil spirit which will be alive until someone believe in it.

Categories