I'm building a building a website using the Reddit API to display images from Reddit.
I'm getting the data via JSON then use it to build the page, using URLs provided as sources for the images.
Some of the URLs that I get don't go to images directly, but instead to image hosting sites (like imgur.com). Usually, adding '.jpg' at the end of the URL takes me to the right image.
So, doing that, I would like to check if the URL + '.jpg' exists before using it.
I tried to build a function to check the url.
function checkUrl(url){
var request = new XMLHttpRequest;
request.open('GET', url, true);
request.send();
request.onreadystatechange = function(){
if(request.readyState==4){
console.log(request.readyState);
return true;
}else{
return false;
}
}
};
//Then I use the function to check and append the data to the page
var url = url+'.jpg';
if(checkUrl(url)){
//work with the data
}else{
//do nothing
}
Nothing happens to the page, still I get the readyState logged into the console, so the checkUrl() function seems to be returning true.
What I am doing wrong ? I am pretty new to the whole Ajax thing, so some help would very appreciated.
Thank you
Your problem is that when request.readyState == 4 this means the request has completed, regardless of what the result of that request was. So even if the URL you request returns a "404 not found", you'll still see the XHR resolving itself to readyState 4.
To address what you're trying to do, I'd recommend checking the status code of the response. For example, using your code:
if(request.status==200){
return true;
}
Why your code won't work:
Your AJAX request is asynchronous, and if(checkUrl(url)){ will return null (false) as the function checkUrl() sends the AJAX request and immediately returns, before the AJAX call has completed.
Change
request.open('GET', url, true);
to
request.open('GET', url, false);
Also, move your request.send() to after the request.onreadystatechange() as now it is a non-async request.
request.onreadystatechange = function(){
if(request.readyState==4){
console.log(request.readyState);
return true;
}else{
return false;
}
}
request.send();
Or, you could simply place your check logic into the onreadystatechange function:
request.onreadystatechange = function(){
var url = url+'.jpg';
if(request.readyState==4){
//work with the data
}else{
//do nothing
}
}
I believe your problem is misunderstanding of AJAX; AJAX is basically asynchronous, and that's why the behavior you are describing.
I've used the following to get a simple true/false indication whether a URL is valid, in a synchronous manner:
function isValidURL(url) {
var encodedURL = encodeURIComponent(url);
var isValid = false;
$.ajax({
url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + encodedURL + "%22&format=json",
type: "get",
async: false,
dataType: "json",
success: function(data) {
isValid = data.query.results != null;
},
error: function(){
isValid = false;
}
});
return isValid;
}
The usage is then trivial:
var isValid = isValidURL("http://www.wix.com");
alert(isValid ? "Valid URL!!!" : "Damn...");
Hope this helps
The return value of request.reonreadystatechange is not the return value of checkUrl. Try this:
function checkUrl(url){
var request = new XMLHttpRequest;
request.open('GET', url, true);
request.send();
request.onreadystatechange = function(){
if(request.readyState==4){
console.log(request.readyState);
// perform your data manipulation here
// don't separate it with the request
}
}
};
On Safari, ActiveXObject will work fine, compared to XMLHttpRequest:
function isThere(url)
{
var req= new AJ(); // XMLHttpRequest object
try {
req.open("HEAD", url, false);
req.send(null);
//alert(req.status); //un-comment if need alert for status code
return req.status== 200 ? true : false;
}
catch (er) {
//alert ('ERROR:'); // un-comment if need alert for error
return false;
}
}
function AJAX()
{
var obj;
if (window.XMLHttpRequest) obj= new XMLHttpRequest();
else if (window.ActiveXObject)
{
try
{
obj= new ActiveXObject('MSXML2.XMLHTTP.3.0');
}
catch(er)
{
try
{
obj= new ActiveXObject("Microsoft.XMLHTTP");
}
catch(er)
{
obj= false;
}
}
}
return obj;
}
Related
this is my ajax code
function buatajax(){
if(window.XMLHttpRequest){
return new XMLHttpRequest();
}
if(window.ActiveXObject){
return new ActiveXObject("Microsoft.XMLHTTP");
}
return null;
}
function checkout() {
var url = "index3.php";
url = url+"&sid="+Math.random();
ajaxku = buatajax();
ajaxku.onreadystatechange=checkoutisi;
ajaxku.open("GET",url,true);
ajaxku.send(null);
}
function checkoutisi() {
if(ajaxku.readyState == 4){
data = ajaxku.responseText;
document.getElementById('isiecon').innerHTML = data;
alert(data);
}
}
when i alert data as it's shown, it said that the requested url not found.
I'm using localhost server for now, instead of using jquery ajax, how to use ajax in my way? because i dont really understand the jquery ajax way.
As the title says, I want to get the Response Header Date value, but I keep getting the following warning :
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help,
check https://xhr.spec.whatwg.org/.
My code :
function getxmlhttp () {
// although IE supports the XMLHttpRequest object, but it does not work on local files.
var forceActiveX = (window.ActiveXObject && location.protocol === "file:");
if (window.XMLHttpRequest && !forceActiveX) {
return new XMLHttpRequest();
}else {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {}
}
alert ("Your browser doesn't support XML handling!");
return null;
};
function srvTime(){
xmlHttp = getxmlhttp();
//xmlHttp.open('HEAD',window.location.href.toString(),false);
//need to send this to a non-volitile page
xmlHttp.open('GET',"blank.php",false);
xmlHttp.setRequestHeader("Content-Type", "text/html");
xmlHttp.send(null);
console.log("raw " + xmlHttp.getResponseHeader("Date"));
return xmlHttp.getResponseHeader("Date");
};
When I switch this line:
xmlHttp.open('GET',"blank.php",true);
To be true, the value returns NULL.
So can this be done, or do I have to just live with the warning in the console?
Thank you
As your title states, you must make the request asynchronously. That means you have to issue the request and wait for it to complete to get the information. Something like this should work:
function srvTime(callback) {
xmlHttp = getxmlhttp();
//xmlHttp.open('HEAD',window.location.href.toString(),false);
//need to send this to a non-volitile page
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4) { // The operation is complete
console.log("raw " + xmlHttp.getResponseHeader("Date"));
callback(xmlHttp.getResponseHeader("Date"));
xmlHttp = null;
}
};
xmlHttp.open('GET', "blank.php", true);
xmlHttp.setRequestHeader("Content-Type", "text/html");
xmlHttp.send(null);
};
Note that you must change the signature of your srvTime method. You can't return the data from it, the caller must supply a callback function that receives the date once the request completes.
An example of how you would use this function with the new signature is as follows:
srvTime(function (serverDate) {
document.getElementById("clock").innerHTML = "Game Time: " + serverDate;
});
I've got a pretty simple function which is designed to grab the form data and send it via a CORS request. Basically it looks like this...
window.onbeforeunload = function() {
formData = getFormData();
logAbandonment(formData);
// return formData;
// alert(formData);
}
function logAbandonment(formData)
{
if(!cors_request) {
cors_request = true;
} else {
return;
}
var url = 'http://mydomain.lan/sub/index.php';
var xhr = createCORSRequest('POST', url);
if (!xhr) {
console.log('Error: CORS not supported.');
}
xhr.send(formData);
}
function createCORSRequest(method, url)
{
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
xhr.onprogress = function () { };
xhr.ontimeout = function () { };
xhr.onerror = function () { };
xhr.onload = function() { };
} else {
// Otherwise, CORS is not supported by the browser.
xhr = null;
}
return xhr;
}
function getFormData()
{
if(typeof FormData == 'undefined') {
return serialize(document.getElementById('AppForm'));
} else {
return new FormData(document.getElementById('AppForm'));
}
}
Because this is IE9 I am working with, I am using the XDomainRequest javascript object.
It is successfully firing the ajax request, but here is where I am having a problem. It is firing it without sending the formData unless I uncomment either of the return or alert lines, in which case it works perfectly. When I do that, I can see the correct data it is supposed to be saying in the alert.
Another thing I noticed is this only happens when I either close the browser or close the tab. If I refresh the page, it works exactly like I want it to.
I thought maybe IE9 had some weird method of destroying the dom before the request was finished going out, but unfortunately, I can't figure out a way to set this to async false on XDomainRequest.
I've also tried setting a timeout, but that seems to break it completely.
Not an answer as much as a work-around, but I found this works perfectly when appending the query string onto the end of the url when calling xdr's open method.
I am using jcaptcha for image verification in my form. Before the form is submitted I make an ajax call using javascript to validate the text entered by the user corresponding to the image displayed. I get the result and update the value of a textbox(imageVerification). After the function that makes this ajax call is executed I pick up the value from this just updated textbox(imageVerification) for the result.
Here is the problem: I am not able to pick up the value from this textbox(imageVerification).
it always shows up as blank.
Catch: if I use an alert() before picking up the value, I am able to pick up the value correctly. I ran this in firebug debug mode and found out that it works in debug mode even without using the alert.
It seemed there is a delay before which the value in the textbox(imageVerification) gets updated. So i introduced a setTimeout() method and was able to pick up the value.
But I dont feel this is the right solution. I am assuming javascript executes sequentially. So why is my statement which is picking up the value after it has been updated by a method not able to get it immediately. Result is even though the image verification is successfull, my check fails since it is not able to pick up the result value from the textbox.
Also, if I use a simple function to update the textbox(imageVerification) instead of a ajax call, I dont face this problem.
Here is the code I am using for the ajax call.
function fetchContainerContent(url, containerid) {
var imageValue = document.forms['ratingForm'].elements['jcaptcha'].value;
var req = false;
var parameterString;
if (window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
} else if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else {
return false;
}
req.onreadystatechange = function() {
requestContainerContent(req, containerid);
}
parameterString = "jcaptcha="+imageValue;
req.open('POST', url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.send(parameterString);
}
function requestContainerContent(req, containerid) {
if (req.readyState == 4 && (req.status==200 || window.location.href.indexOf("http")==-1)){
//document.getElementById(containerid).innerHTML = req.responseText
//document.getElementById(containerid).value=req.responseText;
document.forms['ratingForm'].elements[containerid].value = req.responseText;
}
}
This is the function for image verification:
function validateImage(){
if(isBlank(document.forms['ratingForm'].elements['jcaptcha'].value)){
showError('',"Please enter the text seen in the image above",'jcaptchaError');
return false;
}
fetchContainerContent('captchaController','imageVerification');
var obj = document.forms['ratingForm'].elements['imageVerification'];
//alert('val '+obj.value);
var vall = obj.value;
if(vall=='PASS'){
return true;
}
else{
showError('',"Image verification failed. Please refresh image and try again","jcaptchaError");
return false;
}
}
post my call to fetchContainerContent('captchaController','imageVerification'), the value for imageVerification textbox should be set. If I use the alert box which is commented after the fetchContainerContent('captchaController','imageVerification') call it works fine.
Please help me out. Thanks alot
UPDATED ANSWER: Misread program flow on first pass.
The basic problem is you're trying to get an immediate response from the validateImage() function (return true or false) when the XMLHttpRequest needs time to complete.
Move the actions taken based on the return to their own functions (validFunction, invalidFunction) and try this:
function validateImage() {}
if(isBlank(document.forms['ratingForm'].elements['jcaptcha'].value)){
showError('',"Please enter the text seen in the image above",'jcaptchaError');
return false;
}
var obj = document.forms['ratingForm'].elements['imageVerification'];
validReq = fetchContainerContent('captchaController','imageVerification');
validReq.onload = function () {
var validResp = this.reponseText;
if(validResp=='PASS'){
validFunction();
}
else{
showError('',"Image verification failed. Please refresh image and try again","jcaptchaError");
invalidFunction();
}
}
validReq.send(parameterString);
}
function fetchContainerContent(url, containerid) {
var imageValue = document.forms['ratingForm'].elements['jcaptcha'].value;
var req = false;
var parameterString;
if (window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
} else if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else {
return false;
}
parameterString = "jcaptcha="+imageValue;
req.open('POST', url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
return req;
}
I am using an html form to upload a file to my server. I want to execute a javascript function only after the form has been submitted and the file has been successfully uploaded. The form opens a new page with the text "upload succeeded" if the file upload worked. I tried using a while loop that would loop until the file was found in the database but it crashed my browser. How can I do this? I'm using myform.submit() to submit my form right now.
If the post went well, and you save the file before flushing the page contents, this is easy. The page won't return until the post cycle is ready, so you could insert javascript code to the page after the saving of the file.
You can use AJAX to upload you file and you the async return function (this is a event that will trigger when your request is done) to ether a success or failed message from you php.
EDIT:
Here is a ajax function iv made that u can use, just load this in an extenal file:
var ajax = function(data){
// Return false is no url... You need an url to get url data..
if(typeof data.url !== 'undefined'){
var url = data.url;
// Adept the function depending on your method
if(data.method === 'GET' && data.params !== 'undefined'){
url+='?'+data.params;
}
}else{
return(false);}
var // Set some vars 'n' stuff
method = ( data.method === 'GET') ? 'GET' : 'POST',
params = (typeof data.params !== 'undefined') ? data.params : null,
async = ( data.async === true) ? true : false,
done = (typeof data.done === 'function') ? data.done : false,
return_value = null,
length = (data.method === 'POST') ? data.method.length : '';
var // Find out what ajax methods the browser support
request_method = function(){
var xmlhttp = false;
try {
xmlhttp = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
xmlhttp = false;
}
}
}
return xmlhttp;
}// This thing connet to the server
connect = function(){
if(request = request_method()){}else{
return(false);
}
request.open(method, url, async);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", length);
request.setRequestHeader("Connection", "close");
request.send(params);
request_handle(request);
},// This is where the result get processed
request_handle = function(request){
if(async){
request.onreadystatechange = function() {
if(request.readyState === 4 && request.status === 200) {
done(data);
}
}
}else{
done(data);
}
};
connect();
return(return_value);
}
usage:
ajax({
url: 'test.php',
//// Your ajax request url // no default // Must be set!
method: 'POST',
//// Method of sending ajax data // default is POST
async: true,
//// What to do when done with the request // no default
done: function(http){
table(http,'test');
}
});
one simple thing you can do
use executescalar to insert uploading file as soon as it inserts the file return boolean value to check whether it is inserted,if so then set hiddenfield value. in javascript check the value of the hiddenfield and according to that you can call your javascript function