I'm attempting to catch a potential error on my page, the page has a collection of URLs (retrieved at page load) to various resources which are loaded when needed.
However these resources are only available for a set time, so if the user leaves the page idle for a long period, the URLs may no longer be valid and may return a 403.
I'm currently detecting errors on the resources using something along the lines of:
$(".identifier").on("error", function () {
console.log("Error on resource load");
});
But can I detect the specific type of error / the error code? e.g. the 403 permissions error rather than a generic "There is an error". If possible I would like to be able to react differently to different errors.
Let's say you have all available URL's to your resources inside an array e.g.
var resources = [
"http://url/to/resource-one.fiel",
"http://url/to/resource-two.fiel"
]
Then you could use the following function to check the http response of these resources, by looping over the array and passing each resource to checkResources.
function checkResource (url, index) {
var req = new XMLHttpRequest();
req.open('HEAD', url, true);
req.send();
if (req.status === 404) {
return index;
}
if (req.status === 403) {
return index;
}
};
Or use a specific URL without a loop and delete the index param in the function,
maybe return the URL instead. In other words do an ajax HEAD request, which will only return the headers resource, rather than the resource itself.
You could as well get all the header information or just a specific header info by name like so
xmlhttp.open('HEAD', 'path/to/your/resource', true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
console.log(xmlhttp.getAllResponseHeaders()); // get all header info
console.log(xmlhttp.getResponseHeader("Last-Modified")); // get by name
}
}
xmlhttp.send(null)
Related
My task is to create a web application that lets the user add stuff (such as animals or w/e). To do this I need to use an already built API. The problem is that everytime I try to fetch the information I get errors.
The code is written in javascript. And the task is to use GET, POST and DELETE methods for the API.
The problem is that I keep getting the "Failed to load" error when I try to "send" the request.
Can someone please tell/show me how to do this? I have tried to "Set --allow-file-access-from-file" for chrome but it didn't work.
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (){
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log(xhr.responseText);
}
if (xhr.status == 404) {
console.log("file is not working bitch");
}
}
}
xhr.open('GET','juraland:28d8d7c89a http://juraland-d887642c13.evalcrew.com/dinosaurs?page[number]=0', true);
xhr.send();
That's not the correct format for username/password urls. They should look like
http://username:password#example.com
But note that this is a very old, deprecated technique, as it sends the username and password in the clear; it is not supported in current browsers:
Use of the format "user:password" in the userinfo field is
deprecated. Applications should not render as clear text any data
after the first colon (":") character found within a userinfo
subcomponent unless the data after the colon is the empty string
(indicating no password). Applications may choose to ignore or
reject such data when it is received as part of a reference and
should reject the storage of such data in unencrypted form. The
passing of authentication information in clear text has proven to be
a security risk in almost every case where it has been used.
If the server you're connecting to depends on basic auth you may be able to instead use the method defined in RFC7617, which replaced the original scheme:
To receive authorization, the client
obtains the user-id and password from the user,
constructs the user-pass by concatenating the user-id, a single
colon (":") character, and the password,
encodes the user-pass into an octet sequence (see below for a
discussion of character encoding schemes),
and obtains the basic-credentials by encoding this octet sequence
using Base64 ([RFC4648], Section 4) into a sequence of US-ASCII
characters ([RFC0020]).
...and then pass that encoded string in an Authentication: Basic header rather than as part of the URL.
The URL which you mentioned is wrong i think
"juraland:28d8d7c89a http://juraland-d887642c13.evalcrew.com/dinosaurs?page[number]=0"
"http://juraland-d887642c13.evalcrew.com/dinosaurs?page[number]=0"
This url is working fine.
But while we are sending this through xhr request, the URL is transforming into this
"https://juraland-d887642c13.evalcrew.com/dinosaurs?page[number]=0"
So can you please make the api call in https format?
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (){
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log(xhr.responseText);
}
if (xhr.status == 404) {
console.log("file is not working bitch");
}
}
}
xhr.open('GET','http://juraland-d887642c13.evalcrew.com/dinosaurs?page[number]=0', true);
xhr.send();
First of all, I was using this (maybe old) code in Javascript:
function GetJson(url)
{
// 1. New Object XMLHttpRequest
var xhr = new XMLHttpRequest();
// 2. Config it
xhr.open('GET', url, false);
// 3. Send request
xhr.send();
// 4. Errors
if (xhr.status != 200) {
// Responce error out
return( xhr.status + ': ' + xhr.statusText ); // 404: Not Found
} else {
// Responce result
return( xhr.responseText ); // responseText --
}
}
This code solved the problem. Until this URL came:
https://bittrex.com/api/v1.1/public/getmarketsummaries/
The first error I encountered is:
XMLHttpRequest can not load
https://bittrex.com/api/v1.1/public/getmarketsummaries/. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'file: //' is therefore not allowed access.
To not change anything in the browser, long searches have led me to the fetch() function. But I categorically cannot understand how to get a response from the server in the form of JSON or at least in the form of text (for further conversion to JSON)
I try this:
fetch('https://bittrex.com/api/v1.1/public/getmarketsummaries/',{mode:'no-cors'})
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
And I get the answer:
Looks like there was a problem. Status Code: 0
Is there any way to get the data? It is desirable in a variable. Because I just do not understand how fetch works.
I just need to get data from the API for further processing.
You still have problem with cors. Mode "no-cors" just does not work as you expecting.
What you're dealing with is Cross-Origin Resource Sharing (CORS). The URL you're requesting the data from doesn't allow the data to be fetched from another domain. The reason your second snippet works is because you set the mode to no-cors. The call will succeed but your code won't be able to access any of the data. It is kinda useless for your purpose.
Heres my email sending function:
function send() {
var key = "dJdJekCVAFIqvUJ13DEczZjgIh_4MyeIGEHz2GBYKFe";
var message_name = "defender_send_message";
var data = {};
data.value1 = document.getElementById('textBox').value;
data.value2 = localStorage.getItem("AdminsEmail");
var url = "https://maker.ifttt.com/trigger/" + message_name + "/with/key/" + key;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
console.log("Message Sent");
}
}
}
xmlhttp.open('POST', url, true);
xmlhttp.responseType = 'json';
xmlhttp.send(new FormData(data));
}
I wanted to create an email sending function with only pure js, not jquery or anything. I get the following errors when i click send:
(ignore the first error i fixed that already)
I had a jquery function that worked (but i had to get rid of it):
var message = localStorage.getItem("Message");
console.log(message + localStorage.getItem("AdminsEmail"));
var key = "dJdJekCVAFIqvUJ13DEczZjgIh_4MyeIGEHz2GBYKFe"; // << YOUR KEY HERE
var message_name = "defender_send_message"; // << YOUR MESSAGE NAME HERE
var url = "https://maker.ifttt.com/trigger/" + message_name + "/with/key/" + key;
$.ajax({
url: url,
data: {value1: message,
value2: localStorage.getItem("AdminsEmail")},
dataType: "jsonp",
complete: function(jqXHR, textStatus) {
console.log("Message Sent");
}
});
why would this work and my other function not?
EDIT 2 : Since it seems the endpoint doesn't actually return JSON, I think your original jQuery code wasn't correct either. You need to do more research into this iftt.com platform and how to use it. From what I can tell, it's meant to be used in a mobile app, not in the browser- it would be a normal POST XHR then, and CORS doesn't apply to mobile apps. They have this page for testing the endpoint- notice that it gives you an example using curl, a command-line tool, where again CORS doesn't apply. So I think you need to rethink things, this service is not designed to be used from a browser, like you are trying to do.
EDIT: since it turns out you are actually trying to use JSONP and not a plain XHR, all you need to do is implement that without jQuery- create a script tag with the server's URL and add a URL parameter to define your callback function to handle the data. This answer should give you the solution.
In your case the code might look like this :
http://www.codeply.com/go/bp/VRCwId81Vr
function foo(data)
{
// do stuff with JSON
console.log(data)
}
var script = document.createElement('script');
script.src = "https://maker.ifttt.com/trigger/defender_send_message/with/key/"+
"dJdJekCVAFIqvUJ13DEczZjgIh_4MyeIGEHz2GBYKFe?callback=foo";
document.getElementsByTagName('head')[0].appendChild(script);
Note that this doesn't work for me(but with your code, you would get Message sent printed to the console, so maybe you thought it was working?)- the response isn't JSON. Most likely the endpoint isn't actually meant to be used for JSONP?
My answer below only applies if you are trying to do a regular XHR in a browser without JSONP.
This happens because of the Cross Origin Resource Sharing policy of your browser. Your code is hosted at localhost, and it is trying to access a resource hosted at maker.ifttt.com through an XmlHttpRequest. In order to allow this to happen, the server at maker.ifttt.com would need to be configured to allow access from the localhost origin. Presumably you can not make that change as you don't control that server.
In your case, the best solution would be to make the request to maker.ifttt.com through your own server- CORS doesn't apply for server-to-server requests. Send the XmlHttpRequest to your server, take the data regarding the email from the request URL parameters, and then make the request to maker.ifttt.com using that data.
I'm trying to get posts from my tumblr blog and put them on a separate website page. To do this I registered an app on their OAuth page, but I'm having some issues when I try to actually request the authorization. My console spits out this message—
XMLHttpRequest cannot load https://api.tumblr.com/v2/blog/myblog.tumblr.com/posts?api_key=(MY_KEY).
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://127.0.0.1:63342' is therefore not allowed access.
(I've omitted the key value here for obvious reasons).
Now, my site isn't actually live yet, and I have a test server running at localhost:63342 but on their OAuth app settings page I have these options that I must fill out—
Is there a way to get this to work with my local test server? Here's the code that I'm calling to request access.
var request = new XMLHttpRequest();
request.open('GET', 'https://api.tumblr.com/v2/blog/myblog.tumblr.com/posts?api_key=(API_KEY)', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var data = JSON.parse(request.responseText);
console.log(data);
} else {
// We reached our target server, but it returned an error
console.log('server error');
}
};
request.onerror = function() {
// There was a connection error of some sort
console.log("ERROR!!!");
};
request.send();
Any help would be appreciated! Thanks!
Turn out my issue was using JSON instead of JSONP, which bypasses the Access-Control-Allow-Origin issue. I downloaded this JSONP library for Javascript ( I am not using JQuery in my project ) and was able to access the api by writing this:
JSONP('https://api.tumblr.com/v2/blog/myblog.tumblr.com/posts?api_key=(API_KEY)'
, function(data) {
console.log(data);
});
Which returns a JSON Object which I can then data from using something like data.response or whatever objects are in the array.
Again, my issue was not Tumblr not authorizing my test server. I was able to get this to work using 127.0.0.1:port as my application website & callback url.
I developed a small Javascript/jQuery program to access a collection of pdf files for internal use. And I wanted to have the information div of a pdf file highlighted if the file actually exist.
Is there a way to programmatically determine if a link to a file is broken? If so, How?
Any guide or suggestion is appropriated.
If the files are on the same domain, then you can use AJAX to test for their existence as Alex Sexton said; however, you should not use the GET method, just HEAD and then check the HTTP status for the expect value (200, or just less than 400).
Here's a simple method provided from a related question:
function urlExists(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
callback(xhr.status < 400);
}
};
xhr.open('HEAD', url);
xhr.send();
}
urlExists(someUrl, function(exists) {
console.log('"%s" exists?', someUrl, exists);
});
Issue is that JavaScript has the same origin policy so you can not grab content from another domain. This won't change by upvoting it (wondering about the 17 votes).
I think you need it for external links, so it is impossible just with .js ...
If the files are not on an external website, you could try making an ajax request for each file. If it comes back as a failure, then you know it doesn't exist, otherwise, if it completes and/or takes longer than a given threshold to return, you can guess that it exists. It's not always perfect, but generally 'filenotfound' requests are quick.
var threshold = 500,
successFunc = function(){ console.log('It exists!'); };
var myXHR = $.ajax({
url: $('#checkme').attr('href'),
type: 'text',
method: 'get',
error: function() {
console.log('file does not exist');
},
success: successFunc
});
setTimeout(function(){
myXHR.abort();
successFunc();
}, threshold);
You can $.ajax to it. If file does not exist you will get 404 error and then you can do whatever you need (UI-wise) in the error callback. It's up to you how to trigger the request (timer?) Of course if you also have ability to do some server-side coding you can do a single AJAX request - scan the directory and then return results as say JSON.
Like Sebastian says it is not possible due to the same origin policy. If the site can be published (temporarily) on a public domain you could use one of the link checker services out there. I am behind checkerr.org
As others have mentioned, because of JavaScript's same origin policy, simply using the function from the accepted answer does not work. A workaround to this is to use a proxy server. You don't have to use your own proxy for this, you can use this service for example: https://cors-escape.herokuapp.com (code here).
The code looks like this:
var proxyUrl = "https://cors-anywhere.herokuapp.com/";
function urlExists(url, callback) {
var sameOriginURL = proxyUrl + url;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
callback(xhr.status < 400);
}
};
xhr.open('HEAD', sameOriginURL);
xhr.send();
}
urlExists(someUrl, function(exists) {
console.log('"%s" exists?', someUrl, exists);
});