Javascript - Check if (URL)-file exists over HTTPS - javascript

I already tried getting the file with this Code, the problem is, the code works with http requests but not with https request (which is what i need)
function isThere(url) {
var req = new XMLHttpRequest(); // XMLHttpRequest object
try {
req.open("HEAD", url, false);
req.send(null);
return req.status == 200 ? true : false;
} catch (er) {
return false;
}
}
function setUser() {
var user = document.getElementById("userName").value;
if (isThere("https://dev.sentinex.de/ulogv2/" + user) == true) {
alert("File exists!");
} else {
alert("File doesn't exist!");
}
}
Does anyone know how i can change the code to work with HTTPS Requests or how i could rewrite it so that i could get HTTPS Requests?
PS: I am just requesting from my own domain - so no other domains for requests are needed.

Please posts the domain of the resource that executes the code.
If you are on Http. You must use a bypassSecurityTrust

Related

Getting A Cross-Origin XmlHttpRequest to Return an XML File in HTML5

EDIT: REMEMBER TO ALWAYS CHECK YOUR NETWORK TAB FOR ERRORS, MY POSTED ANSWER ELABORATES THAT THIS WAS A STUPID QUESTION ON MY PART, THANKS epascarello
I'm writing some backend code for an HTML5 website and I can't get this very important function to work. The site will often need to dynamically pull PHP-generated XML files from a different server. I'm pretty sure that server has Access-Control-Allow-Origin set to allow requests from this server. I will verify with my boss but he's out for a couple days and honestly it's more likely something I'm doing wrong. Does anyone see something wrong with this code?
Notice I have an alert at the bottom before request.send(null) and after. .send() works fine and the function completes if I request an XML file from the same server, but if I request from the other I get the "before" alert but not the "after". I am also seeing no errors or other alerts displayed to me.
Notes:
There are some references to global variables and such in other .js files. I've determined that including them would be pointless and just clutter the question.
'cross' is just a boolean for whether the request is cross origin, to another server.
function createXmlHttpRequestObject(cross) {
if(cross === undefined) {
cross = false;
}
var xmlHttp;
if(cross) {
if(window.XDomainRequest) {
try {
xmlHttp = new window.XDomainRequest();
} catch(e) {
xmlHttp = false;
}
} else {
xmlHttp = new XMLHttpRequest();
}
} else {
if(window.ActiveXObject) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
xmlHttp = false;
}
} else {
try {
xmlHttp = new XMLHttpRequest();
} catch(e) {
xmlHttp = false;
}
}
}
if(!xmlHttp) {
alert ("Error: CREATING XMLHTTP REQUEST OBJECT FAILED");
} else {
return xmlHttp;
}
}
//receives xml object from file
function getXmlObject(URL) {
//if url contains any of site root, then it is not cross domain
var cross = false;
if(!URL.includes(url_home)) {
cross = true;
}
var request = createXmlHttpRequestObject(cross);
var response;
if(window.ActiveXObject || window.XDomainRequest) {
request.onload = function(){
response = request.responseXML;
};
request.open('GET',URL,false);
request.send(null);
} else {
request.open('GET',URL,false);
request.onreadystatechange = function(){
if(request.readyState == 4) {
if(request.status == 200) {
response = request.responseXML;
} else {
var warn = 'NOT FOUND\n' + URL;
response = warn;
alert(warn);
}
}
};
alert("before");
request.send(null);
alert("after");
}
return response;
}
Found in the network tab confirmation that there is in fact no Access-Control-Allow-Origin flag on the server I'm trying to access. I'm gonna have to talk to the right people and see if that can change. Still, if this code can be improved or if there's still an issue here I'm not seeing please point it out.

phonegap + iOS, http request always return status 0 on local files

I am using Phonegap 3.3.0 and on iOS, the following http request always returns 0, whether the file exists or not !!
var url = './images/pros/imagefile.png';
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
http.status
It returns 0 if the file exists, but if I try a fake wrong url :
var url = 'httpbabla/images/pros/imagefile.pngfkjdqmkfjdmqsl';
or
var url = 'www/images/pros/imagefidddddddle.pngooijijijiojs';
it still returns 0.
Is it a phonegap bug ? If not, then how to quickly distinguish existing local files from unexisting files with Phonegap and iOS?
Thanks
You might have better luck with an asynchronous request and onload and onerror handlers. Note the use of a true parameter as the last argument to http.open:
var url = 'file:///does/not/exist.jpg';
var http = new XMLHttpRequest();
http.open('HEAD', url, true);
http.onload = function(e){/* Success! File exists; process the response... */};
http.onerror = function(e){/* Failed - file does not exist - do whatever needs to be done... */};
http.send();
Once you call http.send your function will be done and control will return to the caller. Whatever processing you need to do on either success or failure will need to be taken care of in the onload and onerror callbacks. Take the time to learn how to use Javascript callbacks (and closures) if you're not familiar with them - they're one of the most powerful features in the language.
This works for me :
function UrlExists(url)
{
if ( isPhoneGap && isIOS() ) {
if (url.fileExists()){ //see prototype below
return true;
}else {
return false;
}
} else {
try {
http = new XMLHttpRequest();
http.open("HEAD", url, false);
http.send();
}
catch (err) {
//alert("An error:" + err.name + "---" + err.message);
}
//return http.status!=404;
if (http.readyState == 4) {
console.log("http.status="+http.status);
return http.status==200 || http.status==0;
}
}
}
// check local file existance for iOS
String.prototype.fileExists = function() {
filename = this.trim();
var response = jQuery.ajax({
url: filename,
type: 'HEAD',
async: false
}).status;
return (response != "200") ? false : true;
}

Repeat failed XHR

Is there any common way, example or code template how to repeat a XHR that failed due to connection problems?
Preferably in jQuery but other ideas are welcome.
I need to send some application state data to a database server. This is initiated by the user clicking a button. If the XHR fails for some reason I need to make sure that the data is sent later (no interaction needed here) in the correct order (the user may press the button again).
Here's how I would do it:
function send(address, data) {
var retries = 5;
function makeReq() {
if(address == null)
throw "Error: File not defined."
var req = (window.XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
if(req == null)
throw "Error: XMLHttpRequest failed to initiate.";
req.onload = function() {
//Everything's peachy
console.log("Success!");
}
req.onerror = function() {
retries--;
if(retries > 0) {
console.log("Retrying...");
setTimeout(function(){makeReq()}, 1000);
} else {
//I tried and I tried, but it just wouldn't work!
console.log("No go Joe");
}
}
try {
req.open("POST", address, true);
req.send(data); //Send whatever here
} catch(e) {
throw "Error retrieving data file. Some browsers only accept cross-domain request with HTTP.";
}
}
makeReq();
}
send("somefile.php", "data");
To make sure everything is sent in the right order, you could tack on some ID variables to the send function. This would all happen server-side though.
And of course, there doesn't need to be a limit on retries.
jQuery provides an error callback in .ajax for this:
$.ajax({
url: 'your/url/here.php',
error: function(xhr, status, error) {
// The status returns a string, and error is the server error response.
// You want to check if there was a timeout:
if(status == 'timeout') {
$.ajax();
}
}
});
See the jQuery docs for more info.

How do I check if file exists in jQuery or pure JavaScript?

How do I check if a file on my server exists in jQuery or pure JavaScript?
With jQuery:
$.ajax({
url:'http://www.example.com/somefile.ext',
type:'HEAD',
error: function()
{
//file not exists
},
success: function()
{
//file exists
}
});
EDIT:
Here is the code for checking 404 status, without using jQuery
function UrlExists(url)
{
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status!=404;
}
Small changes and it could check for status HTTP status code 200 (success), instead.
EDIT 2: Since sync XMLHttpRequest is deprecated, you can add a utility method like this to do it async:
function executeIfFileExist(src, callback) {
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if (this.readyState === this.DONE) {
callback()
}
}
xhr.open('HEAD', src)
}
A similar and more up-to-date approach.
$.get(url)
.done(function() {
// exists code
}).fail(function() {
// not exists code
})
This works for me:
function ImageExist(url)
{
var img = new Image();
img.src = url;
return img.height != 0;
}
i used this script to add alternative image
function imgError()
{
alert('The image could not be loaded.');
}
HTML:
<img src="image.gif" onerror="imgError()" />
http://wap.w3schools.com/jsref/event_onerror.asp
So long as you're testing files on the same domain this should work:
function fileExists(url) {
if(url){
var req = new XMLHttpRequest();
req.open('GET', url, false);
req.send();
return req.status==200;
} else {
return false;
}
}
Please note, this example is using a GET request, which besides getting the headers (all you need to check weather the file exists) gets the whole file.
If the file is big enough this method can take a while to complete.
The better way to do this would be changing this line: req.open('GET', url, false); to req.open('HEAD', url, false);
Here's how to do it ES7 way, if you're using Babel transpiler or Typescript 2:
async function isUrlFound(url) {
try {
const response = await fetch(url, {
method: 'HEAD',
cache: 'no-cache'
});
return response.status === 200;
} catch(error) {
// console.log(error);
return false;
}
}
Then inside your other async scope, you can easily check whether url exist:
const isValidUrl = await isUrlFound('http://www.example.com/somefile.ext');
console.log(isValidUrl); // true || false
I was getting a cross domain permissions issue when trying to run the answer to this question so I went with:
function UrlExists(url) {
$('<img src="'+ url +'">').load(function() {
return true;
}).bind('error', function() {
return false;
});
}
It seems to work great, hope this helps someone!
All the other answers can fail due to cache!
Making a HTTP request to a file on server can be intercepted with HTTP cache and the cached response is then returned. But the file may be deleted on the server in the meantime, so ignoring cache may return false positive results.
Proper solution would be to create non-cached HTTP HEAD request. Nik Sumeiko's answer uses no-cache header which means that the response can be cached, but must be revalidated before reuse. In this case the server may return 304: Not Modified, which is not 200: OK and thus false negative.
To avoid cache, the correct header is Cache-Control: no-store
File can exist without HTTP 200 response
You should also keep in mind that redirection (301: Moved Permanently, 307: Temporary Redirect or 308: Permanent Redirect) may occur, so the file can exist elsewhere and may be returned from different location: depending on the use-case, one may choose to follow redirection instead of returning false in this case.
Also keep in mind that background requests will be blocked if you check file existence on different domain and its CORS policy is not opened to your server. In this case 403: Forbidden is usually returned, which doesn't mean file does not exist but file is unavailable. Last but not least, the same applies to 500: Internal Server Error response, which means that the HTTP server failed to handle the request, but the file can be available otherwise, like by FTP.
The following code will return true if the file exists, false if not or undefined if the file is unavailable or redirected:
const fileExists = file =>
fetch(file, {method: 'HEAD', cache: 'no-store'})
.then(response => ({200: true, 404: false})[response.status])
.catch(exception => undefined);
fileExists("yourFile.html").then(yes => yes && alert("yourFile.html exists"));
// or in the async scope...
let yourFileExists = await fileExists("yourFile.html");
if(yourFileExists) console.log("It is there!")
else if(yourFileExists===false) console.log("Nope, it was deleted.");
else console.log("You are not worthy the answer, puny human!");
Modern and obsolete approaches
Since we live in the future now, I would also recommend:
$.ajax() obsolete, don't use in new projects
XMLHttpRequest() obsolete, don't use in new projects
fetch() modern approach, use it if you are free to choose
Note GET/POST methods (like <img src...>) are not appropriate here as they waste network traffic by downloading the file (imagine the worst scenario with high resolution photo and user with paid mobile data in area with poor connectivity)
Note Modern PWA approach is to use Cache API with serviceWorker's fetch event which intercepts the communication between the client and HTTP cache. In the example in the link, there should be something like
if(event.request.cache=="no-store") {
// avoid cache storage and pass the request in the chain
// client - cache storage - HTTP cache - server
return fetch(event.request);
}
Without this, the cache settings may be ignored and there may be no way to detect the remote file existence from the main thread with the serviceWorker running - illustrated
here.
JavaScript function to check if a file exists:
function doesFileExist(urlToFile)
{
var xhr = new XMLHttpRequest();
xhr.open('HEAD', urlToFile, false);
xhr.send();
if (xhr.status == "404") {
console.log("File doesn't exist");
return false;
} else {
console.log("File exists");
return true;
}
}
I use this script to check if a file exists (also it handles the cross origin issue):
$.ajax(url, {
method: 'GET',
dataType: 'jsonp'
})
.done(function(response) {
// exists code
}).fail(function(response) {
// doesnt exist
})
Note that the following syntax error is thrown when the file being checked doesn't contain JSON.
Uncaught SyntaxError: Unexpected token <
For a client computer this can be achieved by:
try
{
var myObject, f;
myObject = new ActiveXObject("Scripting.FileSystemObject");
f = myObject.GetFile("C:\\img.txt");
f.Move("E:\\jarvis\\Images\\");
}
catch(err)
{
alert("file does not exist")
}
This is my program to transfer a file to a specific location and shows alert if it does not exist
An async call to see if a file exists is the better approach, because it doesn't degrade the user experience by waiting for a response from the server. If you make a call to .open with the third parameter set to false (as in many examples above, for example http.open('HEAD', url, false); ), this is a synchronous call, and you get a warning in the browser console.
A better approach is:
function fetchStatus( address ) {
var client = new XMLHttpRequest();
client.onload = function() {
// in case of network errors this might not give reliable results
returnStatus( this.status );
}
client.open( "HEAD", address, true );
client.send();
}
function returnStatus( status ) {
if ( status === 200 ) {
console.log( 'file exists!' );
}
else {
console.log( 'file does not exist! status: ' + status );
}
}
source: https://xhr.spec.whatwg.org/
This is an adaptation to the accepted answer, but I couldn't get what I needed from the answer, and had to test this worked as it was a hunch, so i'm putting my solution up here.
We needed to verify a local file existed, and only allow the file (a PDF) to open if it existed. If you omit the URL of the website, the browser will automatically determine the host name - making it work in localhost and on the server:
$.ajax({
url: 'YourFolderOnWebsite/' + SomeDynamicVariable + '.pdf',
type: 'HEAD',
error: function () {
//file not exists
alert('PDF does not exist');
},
success: function () {
//file exists
window.open('YourFolderOnWebsite/' + SomeDynamicVariable + '.pdf', "_blank", "fullscreen=yes");
}
});
First creates the function
$.UrlExists = function(url) {
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status!=404;
}
After using the function as follows
if($.UrlExists("urlimg")){
foto = "img1.jpg";
}else{
foto = "img2.jpg";
}
$('<img>').attr('src',foto);
Here's my working Async Pure Javascript from 2020
function testFileExists(src, successFunc, failFunc) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState === this.DONE) {
if (xhr.status === 200) {
successFunc(xhr);
} else {
failFunc(xhr);
}
}
}
// xhr.error = function() {
// failFunc(xhr);
// }
// xhr.onabort = function() {
// failFunc(xhr);
// }
// xhr.timeout = function() {
// failFunc(xhr);
// }
xhr.timeout = 5000; // TIMEOUT SET TO PREFERENCE (5 SEC)
xhr.open('HEAD', src, true);
xhr.send(null); // VERY IMPORTANT
}
function fileExists(xhr) {
alert("File exists !! Yay !!");
}
function fileNotFound(xhr) {
alert("Cannot find the file, bummer");
}
testFileExists("test.html", fileExists, fileNotFound);
I could not force it to come back with any of the abort, error, or timeout callbacks.
Each one of these returned a main status code of 0, in the test above, so
I removed them. You can experiment.
I set the timeout to 5 seconds as the default seems to be very excessive.
With the Async call, it doesn't seem to do anything without the send() command.
What you'd have to do is send a request to the server for it to do the check, and then send back the result to you.
What type of server are you trying to communicate with? You may need to write a small service to respond to the request.
This doesn't address the OP's question, but for anyone who is returning results from a database: here's a simple method I used.
If the user didn't upload an avatar the avatar field would be NULL, so I'd insert a default avatar image from the img directory.
function getAvatar(avatar) {
if(avatar == null) {
return '/img/avatar.jpg';
} else {
return '/avi/' + avatar;
}
}
then
<img src="' + getAvatar(data.user.avatar) + '" alt="">
It works for me, use iframe to ignore browsers show GET error message
var imgFrame = $('<iframe><img src="' + path + '" /></iframe>');
if ($(imgFrame).find('img').attr('width') > 0) {
// do something
} else {
// do something
}
I wanted a function that would return a boolean, I encountered problems related to closure and asynchronicity. I solved this way:
checkFileExistence= function (file){
result=false;
jQuery.ajaxSetup({async:false});
$.get(file)
.done(function() {
result=true;
})
.fail(function() {
result=false;
})
jQuery.ajaxSetup({async:true});
return(result);
},

How can I check existence of a file with JavaScript?

How can I check an existence of a file (It is an xml file that I would like to check in this case) with JavaScript?
if you're using jQuery, you can try to load the file
$.ajax({
type: "GET",
url: "/some.xml",
success: function()
{ /** found! **/},
error: function(xhr, status, error) {
if(xhr.status==404)
{ /** not found! **/}
}
});
if you're not using jQuery:
function ajaxRequest(){
var activexmodes=["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"]
//Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
if (window.ActiveXObject){
for (var i=0; i<activexmodes.length; i++){
try{
return new ActiveXObject(activexmodes[i])
}
catch(e){
//suppress error
}
}
}
else if (window.XMLHttpRequest) // if Mozilla, Safari etc
return new XMLHttpRequest()
else
return false
}
var myrequest=new ajaxRequest()
myrequest.onreadystatechange=function(){
if (myrequest.readyState==4){ //if request has completed
if (myrequest.status==200 || window.location.href.indexOf("http")==-1){
// FOUND!
}
}
}
myrequest.open('GET', 'http://blabla.com/somefile.xml', true);
If the file is located on the same host that served the page containing the javascript you could try sending an ajax request and verify the returned status code:
function checkFile(fileUrl) {
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('HEAD', fileUrl, true);
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
if (self.xmlHttpReq.status == 200) {
alert('the file exists');
} else if (self.xmlHttpReq.status == 404) {
alert('the file does not exist');
}
}
}
self.xmlHttpReq.send();
}
checkFile('/somefile.xml');
Javascript doesn't really have any file handling functions. Your best bet is to do the check server side and send some context back to the client.
If you want to get super hacky you COULD call an xmlHttpRequest (If you're using jQuery take a look at the $.ajax function)
Once you call $.ajax you can use the success/error handlers to determine what to do. It should spit out an error if the file doesn't exist.
This of course is NOT a recommended way to do this.
I don't have enough reputation to post comments so let me note that in the Anwar Chandra's answer (non-jQuery version) you have to call eventually:
myrequest.send();
Also, the HEAD method would be better to "check existence of a file", because you don't need to read the whole file from the server.

Categories

Resources