I have a simple regex function in jQuery to add an image tag to image URLs posted by users.
So that when a user posts for example www.example.com/image.jpg the image tag will be added so that user can see the image without clicking on the URL.
var hostname = window.location.hostname.replace(/\./g,'\\.');
var re = new RegExp('(http:\\/\\/[^' + hostname + ']\\S+[\\.jpeg|\\.png|\\.jpg|\\.gif])','g');
$(".texthold ").each(function() {
$(this).html($(this).html().replace(re, '<img src="$1" />'));
});
How can I check the file size of the image before allowing it to be viewable? So that if for example the image file size is bigger than 5MB the image will not be displayed and instead the URL will be shown.
var url = ...; // here you build URL from regexp result
var req = $.ajax({
type: "HEAD",
url: url,
success: function () {
if(req.getResponseHeader("Content-Length") < 5 * 1048576) // less than 5 MB?
; // render image tag
else
; // render URL as text
}
});
You will only be able to accomplish what you want if the server response for the images includes the appropriate Cross Origin Resource Sharing (CORS) header and a content-length header.
Additionally you will need to take into account the time required for the ajax requests to be fulfilled in your replacement loop.
Below is a jQuery (1.9.1) example which demonstrates what the final solution could look like. For it to work you will need to update the links to a server which returns proper CORS headers or disable security on your browser. The example is also on jsfiddle.
var largeImage = "http://eoimages.gsfc.nasa.gov/images/imagerecords/49000/49684/rikuzentakata_ast_2011073_lrg.jpg";
var smallImage = "http://eoimages.gsfc.nasa.gov/images/imagerecords/81000/81258/kamchatka_amo_2013143_tn.jpg";
var urls = [largeImage, smallImage];
var maxSize = 5000000;
$.each(urls, function(index, value) {
conditionalMarkupUpdater(value, maxSize);
});
var onShouldBeViewable = function () {
alert('This is a small image...Display it.');
};
var onShouldNotBeViewable = function () {
alert('This is a large image...Only provide the url.');
};
var onError = function() {
alert('There was an error...likely because of CORS issues see http://stackoverflow.com/questions/3102819/chrome-disable-same-origin-policy and http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/"');
};
function checkSize(url) {
var sizeChecker = new jQuery.Deferred();
var onSuccess = function (data, textStatus, jqXHR) {
var length = jqXHR.getResponseHeader('Content-Length');
if (!length) {
sizeChecker.reject("No size given");
} else {
sizeChecker.resolve(parseInt(length));
}
};
var onFailure = function (jqXHR, textStatus, errorThrown) {
sizeChecker.reject("Request failed");
};
$.when($.ajax({
type: "HEAD",
url: url
})).then(onSuccess, onFailure);
return sizeChecker.promise();
};
function conditionalMarkupUpdater(url, maxSize) {
$.when(checkSize(url)).then(
function (size) {
if (size <= maxSize) {
onShouldBeViewable();
} else {
onShouldNotBeViewable();
}
},
function (status) {
onError();
})
};
Related
If there is an img tag in a page whose final image it displays comes after a 302 redirect, is there a way with javascript to obtain what that final URL is after the redirect? Using javascript on img.src just gets the first URL (what's in the page), not what it was redirected to.
Here's a jsfiddle illustration: http://jsfiddle.net/jfriend00/Zp4zG/
No, this is not possible. src is an attribute and it does not change.
I know this question is old, and was already marked answered, but another question that I was trying to answer was marked as a duplicate of this, and I don't see any indication in any of the existing answers that you can get the true URL via the HTTP header. A simple example (assuming a single image tag on your page) would be something like this...
var req = new XMLHttpRequest();
req.onreadystatechange=function() {
if (req.readyState===4) {// && req.status===200) {
alert("actual url: " + req.responseURL);
}
}
req.open('GET', $('img').prop('src'), true);
req.send();
If you are open to using third party proxy this can be done. Obviously not a javascript solution This one uses the proxy service from cors-anywhere.herokuapp.com. Just adding this solution for people who are open to proxies and reluctant to implement this in backend.
Here is a fork of the original fiddle
$.ajaxPrefilter( function (options) {
if (options.crossDomain && jQuery.support.cors) {
var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
options.url = http + '//cors-anywhere.herokuapp.com/' + options.url;
//options.url = "http://cors.corsproxy.io/url=" + options.url;
}
});
$.ajax({
type: 'HEAD', //'GET'
url:document.getElementById("testImage").src,
success: function(data, textStatus, request){
alert(request.getResponseHeader('X-Final-Url'));
},
error: function (request, textStatus, errorThrown) {
alert(request.getResponseHeader('X-Final-Url'));
}
});
based on http://jsfiddle.net/jfriend00/Zp4zG, this snippets works in Firefox 17.0:
alert(document.getElementById("testImage").baseURI)
It doesn't work in Chrome. Not tested anything else-
Here is a workaround that I found out. But it works only if the image on the same domain otherwise you will get an empty string:
var img = document.getElementById("img");
getSrc(img.getAttribute("src"), function (realSrc) {
alert("Real src is: " + realSrc);
});
function getSrc(src, cb) {
var iframe = document.createElement("iframe"),
b = document.getElementsByTagName("body")[0];
iframe.src = src;
iframe.className = "hidden";
iframe.onload = function () {
var val;
try {
val = this.contentWindow.location.href;
} catch (e) {
val = "";
}
if (cb) {
cb(val);
}
b.removeChild(this);
};
b.appendChild(iframe);
}
http://jsfiddle.net/infous/53Layyhg/1/
I initialize Uploadify using the following code:
$('#file1').uploadifive({
'buttonClass': 'upload-btn',
'uploadScript': '/Upload/',
'fileObjName': 'files',
'fileType': 'text/xml',
'formData': { 'uploadType': 'Crew' },
'onUploadComplete': function(file, data) {
var results = $.parseJSON(data);
if (results.error) {
var info = file.queueItem.find('span.fileinfo');
if (info) info.text(' - ' + results.error);
return;
}
window.location.href = '#Url.Content("~/Upload/Checkdata/")' + results.id;
}
});
This works, however I need to modify the formData property when a radio checkbox changes. So, I've tried this:
$('input[name=UploadType]:radio').change(function () {
$('#file1').uploadifive({ 'formData': this.value });
});
However, when that code runs, it breaks the Uploadify control (it now no longer uploads anywhere). I'm guessing because it completely re-initializes the control with all new settings.
How can I update just this one setting? I've read the Uploadify docs and none of them say anything about updating settings; just initializing and calling methods. Thanks!
I've figured out one solution, but not sure if it's the right way to do things (i.e., it might break in future versions of Uploadify).
Basically, it appears you can keep a reference to your configuration around, and update that object at any time:
var uploadifySettings = {
'buttonClass': 'upload-btn',
'uploadScript': '/Upload/',
'fileObjName': 'files',
'fileType': 'text/xml',
'formData': { 'uploadType': 'Crew' },
'onUploadComplete': function(file, data) {
var results = $.parseJSON(data);
if (results.error) {
var info = file.queueItem.find('span.fileinfo');
if (info) info.text(' - ' + results.error);
return;
}
window.location.href = '#Url.Content("~/Upload/Checkdata/")' + results.id;
}
}
$('input[name=UploadType]:radio').change(function () {
uploadifySettings.formData.uploadType = this.value;
});
$('#file1').uploadifive(uploadifySettings);
I work with a large number of images that are stored on a remote server and I'd like to check (with jQuery or JS) which of them are available without loading them entirely. So far I tried 3 solutions, but none of them works like I want:
1.
var http = new XMLHttpRequest();
http.open('HEAD', imageUrl, false);
http.send();
if(http.status >= 400) {
console.log("Error loading " + imageUrl);
}
With this one I get No 'Access-Control-Allow-Origin' header is present on the requested resource....
2.
$.ajax({
type: "HEAD",
async: true,
url: imageUrl
}).done(function() {
}).fail(function() {
console.log("Error loading " + imageUrl);
});
With this one I get the same error as above.
3.
var img = new Image();
img.onerror = function() { console.log("Error loading " + imageUrl) };
img.src = imageUrl;
This one works, but it loads entire images, which makes it very slow.
Yes, third option is the only legal way to do it with JavaScript in this situation. If you care about performance you can use your backend as proxy. You can send images urls array with regular AJAX and ping that urls with you backend.
var imgURL_BASE = "http://www.hayabusa2.jaxa.jp/galleries/onc/nav20181002/";
var imgURL_NAME = "201810021659.jpg"
document.addEventListener('DOMContentLoaded', function() {
var img = document.body.appendChild(document.createElement("img"));
img.onload = function() {
console.log("Image available");
document.getElementById("testresult").innerHTML = "Image found.<br>";
};
img.onerror = function() {
console.log("Image NOT available");
document.getElementById("testresult").innerHTML = "Image not available.<br>";
};
img.src = imgURL_BASE + imgURL_NAME;
});
Check result:
<span id="testresult" name="testresult"></span>
My javascript skills are limited and I'm having a problem with the structure of a series of functions which I think need callbacks. I've been reading a number of posts and tutorials but it's not sticking...yet..
On my page I have a pop up modal which contains an image. If the user clicks the edit button it's to be edited in aviary. Once that's completed the image properties get saved into a database and then the images within the modal box - and the underlying form - should get updated with the edited image.
My series of events starts with the modal opening:
$('#editImageLink2').click(function(event) {
aviaryOnClick('image2', $(this).data('mode'), function(image) {
#do final bits here
});
});
Modal pops up then if the user clicks the edit button this next function starts the editor:
function aviaryOnClick(source, mode) {
editedImage = doAviary(source);
if (editedImage) {
return true;
} else {
return false;
}
}
So - aviary pops up as expected. Then when the user saves the edited image I'm starting to have trouble:
The doAviary function looks like this:
function doAviary(source) {
console.log("hit doAviary", source);
var featherEditor = new Aviary.Feather({
apiKey: 'XXXXXXXX',
apiVersion: 3,
theme: 'dark',
tools: 'all',
displayImageSize: true,
maxSize: 1200,
onSave: function(imageID, newURL) {
//replace image in modal preview
var img = document.getElementById(imageID);
img.src = newURL;
if (newURL != undefined) {
storeImage(newURL, updateFormImage(imageData));
featherEditor.close();
return true;
}
},
onError: function(errorObj) {
alert(errorObj.message);
return false;
}
});
return featherEditor.launch({
image: source,
url: $('#' + source).attr('src')
});
}
So I'm trying to run storeImage in the onSave event, which should then run a callback to the update images with the image data.
My storeImage function:
function storeImage(newURL, imageData) {
var options = new Object();
options.aviaryURL = newURL;
options.mode = mode;
options.dbID = ($('#dbID').val()) ? $('#dbID').val() : null;
//console.log("store image options object:", options);
jQuery.ajax({
url: '/filemanager/aviary',
type: 'POST',
dataType: 'json',
data: options,
complete: function(xhr, textStatus) {
//called when complete
},
success: function(data, textStatus, xhr) {
//called when successful
console.log("finished store image", data);
$.cookie('asset_filename', data.image.filename);
$.cookie('asset_id', data.image.id);
imageData(data);
},
error: function(xhr, textStatus, errorThrown) {
//called when there is an error
imageData(false);
}
});
so IF the image is saved the data should be passed back to the callback. If it fails it's false
Then in the update image function
function updateFormImage(data) {
if (data.result == 'success') {
image = data.image;
#simple updates of elements in page
}
}
My current problem is that on save I'm getting an error imageData is not defined - I'm not sure why this is - if it's waiting for ajax to complete before passing back the data to the callback it should exist.
Why does this error happen?
What better ways are there to refactor this code and use callbacks correctly.
I originally had a callback on the first function but got an error callback function not defined
Confused.
Thanks
imageData is not defined into doAviary.
Also, updateFormImage should return something (imageData).
I'm currently writing an extension using Crossrider, and I need to load an image directly using the URL for doing some image processing on it. However, the onload event doesn't seem to be firing at all.
Am I doing something wrong or is it even possible to do that in a browser extension?
Here is the relevant piece of code:
var imga = document.createElement('img');
imga.src = obj.attr('href'); // URL of the image
imga.style.display = 'none';
imga.onload = function() {
alert('Image loaded');
var imgData = getImageData(imga, 0, imga.height - 3);
alert('Got Image data');
};
EDIT
Here is the full code
function readImage(obj)
{
console.log('Reading');
relayReadImage(obj.attr('href'));
}
function relayReadImage(link)
{
var dateObj = new Date();
var newlink = link + "?t=" + dateObj.getTime();
console.log(newlink);
appAPI.request.get(
{
url: newlink,
onSuccess: function(response, additionalInfo) {
console.log(response);
},
onFailure: function(httpCode) {
alert('GET:: Request failed. HTTP Code: ' + httpCode);
}
});
}
I'm a Crossrider employee and would be happy to help you. If I understand correctly, you are attempting to use the URL (href) of an object in a page's dom (obj.attr('href')) to load the image into a variable in the extension. You can achieve this using our cross-browser appAPI.request.get method in your extension.js file, as follows:
appAPI.ready(function($) {
appAPI.request.get({
url: obj.attr('href'),
onSuccess: function(response) {
var imgData = response;
console.log(imgData);
}
});
});
However, if I've misunderstood your question, please can you clarify the following:
What is the obj object is?
What are you trying to achieve, and in which context (in the Extension or on the Page)?