image polling through javascript - javascript

I need to poll an image using javascript and need to perform an action once the image is found at its position. This is the code I have written for this task.
/*----Image handling script starts here----*/
var beacon = new Image();
beacon.onload = function() {
console.log('Image found');
console.log(this.width,this.height);
window.clearInterval(timer);
};
beacon.onerror = function(){
console.log('Image not found');
}
var timer = window.setInterval(function(){
console.log('sending the request again');
beacon.src = "http://www.google.co.in/logos/2010/lennon10-hp.gif";
},2000);
/*----Image handling script ends here----*/
Problem is that, after one GET request, the response gets cached and request don't get sent everytime I set src. If you examine NET tab, it sends request only on first src set and caches the response.
I need to send a fresh request for image every time my code sets the src. Any workarounds?

Change your src to include the current EPOCH time as a variable.
beacon.src = "http://www.google.co.in/logos/2010/lennon10-hp.gif?" +
date.getTime();
Using a different variable in the query string each time will miss out caching, because as far as the browser is concerned, the image is different (or potentially could be) each time you request the image, and there is no limit to the amount of times you ask, as time hopefully will not stop...

Request the image with a different query string each time. The browser will treat it as a unique URL and won't have it in the cache. You can probably get away with this because it's likely the web server will ignore anything in the query string when requesting an image. The following should make 100 requests:
for (var i=0; i<100; i++)
{
beacon.src = "http://www.google.co.in/logos/2010/lennon10-hp.gif?" + i;
}

Related

Validate if a file exists with JavaScript

Good day. I need to know if the file that I indicate in the path that I save in the text variable "t" as the slide variable "s" exist, in order to be able to show them or not through the view. I need to do this with only java script and local files, no server side. If possible, I would be very grateful to receive your help.
My current code in JavaScript:
function loadFiles(num) {
let s = 'assets/content/Compiladores/Slides/' + num + '.jpg';
let t = 'assets/content/Compiladores/Texts/' + num + '.txt';
document.slider.src = s;
$("#description").load(t);
$("#num").text(num);
}
You are never going to be able to reliably determine if a resource exists before doing something with it.
Note that this holds true even on a program that runs directly on a user's machine or a server. I don't normally mention other people's answers in my own, but the one advocating that you do that check (which per the link is problematic even in the best of circumstances) but across a client-server gap is sheer folly. Think about all the things that can go wrong:
The server could have moved the resource between the time you check and the time you set it.
Another thread or even entire other program could have acquired a lock on the resource causing your request to either take a lot of extra time or fail outright.
The user could be on a mobile connection and lost signal between the time of the check and the time of the resource request.
If you're passing an authentication token the user's session could expire between the time of the check and the time of the actual request.
The server could crash between the first request and the second.
The second request could be load-balanced to a different server than the first request.
The entire network for a major service could go down between the requests. Yes, really.
And so on.
Not to mention that for the happy path it involves a completely unnecessary extra round trip to the server before you start showing them the thing you wanted to show them in the first place!
The correct way to do this is to attempt to load the resource and then just handle the error if it fails:
function loadFiles(num) {
let s = 'assets/content/Compiladores/Slides/' + num + '.jpg';
let t = 'assets/content/Compiladores/Texts/' + num + '.txt';
document.slider.onerror = function () {
// deal with the resource not loading here
}
document.slider.src = s;
const desc = $("#description");
desc.on("error" function () {
// deal with the resource not loading here
});
desc.load(t);
$("#num").text(num);
}
try this for the file exists or not
function UrlExists(url)
{
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status!=404;
}
function UrlExists(url)
{
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status!=404;
}
function loadFiles(num) {
let s = 'assets/content/Compiladores/Slides/' + num + '.jpg';
let t = 'assets/content/Compiladores/Texts/' + num + '.txt';
document.slider.src = s;
if(UrlExists(s)){
$("#description").load(t);
}
if(UrlExists(t)){
$("#num").text(num);
}
}

Auto refresh specific div and load image with jquery/ajax

I have an internet radio station and I need a script that will display a picture of the current song in a particular dvi with an id. The image is automatically uploaded via ftp to the server each time the song changes..
HTML:
<div id="auto"></div>
JS:
$ (document).ready(function() {
$('#auto').html('<img src="artwork.png"></img>');
refresh();
});
function refresh() {
setTimeout (function() {
$('#auto').html('<img src="artwork.png"></img>');
refresh();
}, 1000);
}
I tried this, but all I get is that the image is loaded, but in case of a change, I have to manually refresh the whole page again..
I'll point out multiple things here.
I think your code is just fine if you are going for the setTimeout recursive calls instead of one setInterval action to repeat it.
File Caching
your problem is probably the browser's cache since you are using the same image name and directory all the time. browsers compare the file name and directory and to decide to load it from its cache or else it will request it from the server. there are different tricks you can do to reload the image from the server in this particular case.
Use different file names/directories for the songs loaded dynamically
Use a randomized GET query (e.g. image.png?v=current timestamp)
Your method for switching
you are replacing the file with FTP, I wouldn't recommend that. maybe you should have all your albums and thumbnails uploaded to the server and use a different dynamic switching for efficiency and less error proneness and will help you achieve method #1 in the previous section better.
Loading with constant refresh
I would like to highlight that if you are using nodeJs or nginx servers - which are event based - you can achieve the same functionality with much less traffic. you don't need a refresh method since those servers can actually send data on specific events to the browser telling it to load a specific resource at that time. no constant refresh is required for this.
You consider your options, I tried to be as comprehensive as I could
At the top level, browser cache the image based on its absolute URL. You may add extra query to the url to trick browser that is another new image. In this case, new URL of artist.png will be artist.png?timestamp=123
Check this out for the refresh():
function refresh() {
setTimeout (function() {
var timestamp = new Date().getTime();
// reassign the url to be like artwork.png?timestamp=456784512 based on timestmap
$('#auto').html('<img src="artwork.png?timestamp='+ timestamp +'"></img>');
refresh();
}, 1000);
}
You may assign id attribute to the image and change its src url
html
<img id="myArtworkId" src="artwork.png"/>
js in the refresh method
$('#myArtworkId').attr('src', 'artwork.png?timestamp=' + new Date().getTime());
You can use window.setInterval() to call a method every x seconds and clearInterval() to stop calling that method. View this answer for more information on this.
// Array containing src for demo
$srcs = ['https://www.petmd.com/sites/default/files/Acute-Dog-Diarrhea-47066074.jpg',
'https://www.catster.com/wp-content/uploads/2018/05/Sad-cat-black-and-white-looking-out-the-window.jpg',
'https://img.buzzfeed.com/buzzfeed-static/static/2017-05/17/13/asset/buzzfeed-prod-fastlane-03/sub-buzz-25320-1495040572-8.jpg?downsize=700:*&output-format=auto&output-quality=auto'
]
$i = 0;
$(document).ready(function() {
$('#auto').html('<img src="https://images.pexels.com/photos/617278/pexels-photo-617278.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"></img>');
// call method after every 2 seconds
window.setInterval(function() {
refresh();
}, 2000);
// To stop the calling of refresh method uncomment the line below
//clearInterval()
});
function refresh() {
$('#auto').html('<img src="' + $srcs[$i++] + '"></img>');
// Handling of index out of bound exception
if ($srcs.length == $i) {
$i = 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="auto"></div>

Periodically Ping and show div on error

I currently have an image which gets pinged in order to only show a div if the local content is available.
But I think a better implementation is to periodically check for ping, at a 30 second interval, then show an #offline div if the image has not been pinged successfully. This is better as it considers that the status of the connection may change without the page having been reloaded.
Original script:
function ImgLoad(myobj){
var randomNum = Date.now() || new Date().getTime();
var oImg=new Image;
oImg.src="http://192.168.8.1/images/ping2.jpg"+"?rand="+randomNum;
oImg.onload=function(){$("#online").show();}
}
I think I have managed to get the function to poll every 30 seconds, but I've not been able to show a div on error rather than if it pings successfully.
function checkping(){
function ImgLoad(myobj){
var randomNum = Date.now() || new Date().getTime();
var oImg=new Image;
oImg.src="http://192.168.8.1/images/ping2.jpg"+"?rand="+randomNum;
oImg.onload=function(){$("#online").show();}
}
}
setInterval(function(){
checkping()}, 30000)
I've not been able to show a div on error
You're already using .onload, just use the corresponding .onerror :
oImg.onerror=function(){$("#error").show();}
Maybe consider "smart" polling instead, which checks your server for the image on incrementally increasing intervals instead of a fixed one.
This link may be of aide: https://github.com/blog/467-smart-js-polling

How to create a cross domain HTTP request

I have a website, and I need a way to get html data from a different website via an http request, and I've looked around for ways to implement it and most say via an ajax call instead.
An ajax call is blocked by linked in so I want to try a plain cross domain http request and hope it's not blocked one way or another.
If you have a server running and are able to run code on it, you can make the HTTP call server side. Keep in mind though that most sites only allow so many calls per IP address so you can't serve a lot of users this way.
This is a simple httpListener that downloads an websites content when the QueryString contains ?site=http://linkedin.com:
// setup an listener
using(var listener = new HttpListener())
{
// on port 8080
listener.Prefixes.Add("http://+:8080/");
listener.Start();
while(true)
{
// wait for a connect
var ctx = listener.GetContext();
var req = ctx.Request;
var resp = ctx.Response;
// default page
var cnt = "<html><body>click me </body></html>";
foreach(var key in req.QueryString.Keys)
{
if (key!=null)
{
// if the url contains ?site=some url to an site
switch(key.ToString())
{
case "site":
// lets download
var wc = new WebClient();
// store html in cnt
cnt = wc.DownloadString(req.QueryString[key.ToString()]);
// when needed you can do caching or processing here
// of the results, depending on your needs
break;
default:
break;
}
}
}
// output whatever is in cnt to the calling browser
using(var sw = new StreamWriter(resp.OutputStream))
{
sw.Write(cnt);
}
}
}
To make above code work you might have to set permissions for the url, if you'r on your development box do:
netsh http add urlacl url=http://+:8080/ user=Everyone listen=yes
On production use sane values for the user.
Once that is set run the above code and point your browser to
http://localhost:8080/
(notice the / at the end)
You'll get a simple page with a link on it:
click me
Clicking that link will send a new request to the httplistener but this time with the query string site=http://linkedin.com. The server side code will fetch the http content that is at the url given, in this case from LinkedIn.com. The result is send back one-on-one to the browser but you can do post-processing/caching etc, depending on your requirements.
Legal notice/disclaimer
Most sites don't like being scraped this way and their Terms of Service might actually forbid it. Make sure you don't do illegal things that either harms site reliability or leads to legal actions against you.

How do I refresh a remote picture?

I have a picture in a DIV on site abc.com which is hosted elsewhere, for example <IMG SRC="http://xyz.com/image.jpg">.
It loads fine, but, I need to update this every few seconds.
The majority of items to upload are local, but the following code will not work for remote pictures:
$('#rightpic').load('http://xyz.com/image.jpg', null);
By trying this, I am getting an error : ...is not allowed by Access-Control-Allow-Origin.
Can anyone recommend a better way of doing this?
Try this out, you want to actually change the src, not use the .load() function.
$('#rightpic').get(0).src = 'http://xyz.com/image.jpg';
.load uses an AJAX request, thus the same origin policy applies - which restricts cross-domain requests. Besides, it's not the best way to load images anyway. Also, setting the same url as src will often load images from the cache.
Instead, you should add a random query string value every request, like a timestamp, to "bust the cache"
var img = document.getElementById('rightpic');
//update every 10 seconds using time from epoch as random value
setInterval(function(){
var randomValue = new Date().getTime();
img.src = "http://example.com/image.jpg?t="+randomvalue;
},10000);

Categories

Resources