I am using Ruby on Rails v3.0.9 and I would like to check if an image (in my case a favicon.ico icon image) is successfully retrieved from a web site and if not I would like to display a custom image.
In order to retrieve the favicon.ico image related to a web site, in my view file I have:
image_tag "#{web_site.link}/favicon.ico", :size => "16x16"
where web_site.link values are something like the followings:
http://stackoverflow.com/
http://www.stackoverflow.com/
http://facebook.com/
...
How to check if an image was found on a web site (maybe using an if ... else ... end statement or performing some HTTP request before to handle favicon images) and how to handle the above scenario?
Here's how to implement the idea you had in the original question.
The issue with this approach will be that your response times will include however long it takes for the other domain to respond to your request for the image. If that site is having
issues, then your page wont load until the request times out.
<%
img_url = 'http://adomain.com/image.jpg'
res = Net::HTTP.get_response(URI.parse(img_url))
img_url = '[my alternate url]' unless res.code.to_i >= 200 && res.code.to_i < 400 #good codes will be betweem 200 - 399
%>
<%=image_tag img_url%>
The jQuery approach is a bit more involved. I'd suggest something along the following:
create an <img> tag with a transparent spacer image
in the page's javascript run a $.ajax call for the remote image
in the success callback replace the <img>'s src with the remote images's url
in the failure callback replace the <img>'s src with the fallback image's url
Unfortunately, I don't have time to generate the exact code for this right now.
You can't do this with Rails unless you fetch the image server-side before rendering the page. What you could do is fetch it in the client with a JavaScript and if there's trouble retrieving it, then switch to an alternative.
Related
I have http://example.com/Image/Show/CwYDBw8LDww where example.com is my site, Show is a method in the Image controller, the unique id CwYDBw8LDww is a key in a database which will point to some other URL on a different domain, e.g. a "hosted" image on Google.
The reason for doing this is that the URLs can get horribly long and unwieldy. I am storing the site content as Markdown/HTML and want to be able to write things like:
<p>Here is an image of a cat.</p>
<img src="http://example.com/Image/Show/CwYDBw8LDww">
and have it render the page as if I put:
<img src="http://googleusercontent.com/SomeReallyReallyReallyLongImageURL.jpg">
So in the database there is a table entry with values:("CwYDBw8LDww", "http://googleusercontent.com/SomeReallyLongImageURL.jpg") which is how I know which "really long URL" belongs to the short code.
I know how to (e.g.) print the 'google' URL to the screen by getting an Action to return it, I am already able to talk to the database, etc. The part I'm missing is getting /Images/Show?shortcode=CwYDBw8LDww to bring back the Google image in a way that it can be rendered on the page. And whether I should be doing that in the View, or what.
My View currently has something like:
#Html.Raw(#Model.ArticleContent)
where the content is already stored as <p>Here is an image of a cat</p> etc.
I solved it myself with a bit of patience and research! I added the following to my Image controller.
public RedirectResult Show(string shortcode)
{
return Redirect(data.GetURL(shortcode));
}
where GetURL() is a method in my data access layer which asks the database for the "long" URL that applies to the shortcode. (I handle cases like if the shortcode doesn't exist in the GetURL() code, so Show() assumes it has been given a valid URL.)
This returns a 302 "Temporary Redirect" HTTP response to re-point the client to the 'new' (Google in my example) URL.
This SO question and answers was helpful in getting to the concept I needed.
I am using MVC3, Razor, C#, EF4.1, MSSQL2008
I have implemented a mechanism to upload files to a web server "Uploads" folder.
The issue I have is that when the user is returned to the "Upload" view, the image is still the old one. This may be linked to the fact that I am using the PK of the User's Organisation as the filename ie 100.png. So swapping the image will produce another 100.png, ie overwrite the original. This prevents lots of rubbish files if I used a GUID instead. However the browser thinks nothing has changed so loads it, I guess, out of cache.
My razor code is:
if (File.Exists(Server.MapPath("~/Uploads/" + strImageFileName)))
{
<p><img alt="Current Image" src="#Href("~/Uploads/" + strImageFileName)"/> </p>
}
else
{
<p><img alt="Current Image" src="#Href("~/Uploads/NoImageFile.png")"/> </p>
}
If I get this issue, then a Shift Refresh usually does the job, although I would like this to be automatic. Is there a way to force a refresh, via code, so the newest Image is always shown. We did seem to have more issues with Chrome for some reason.
Thoughts?
Thanks in advance.
Changing the url referenced by the link seems to be a lightweight solution over using AJAX.
http://www.immense.net/force-update-cached-files-images-favicon/
by adding something arbitrary like a version number. The browser will update the cashed image with the current version.
<img alt="Current Image" src="#Href("~/Uploads/" + strImageFileName + Version )"
you might want to use an action to return the image over a direct url to the image. If you are not already doing so.
I'm using ajax to update a partial, but i would like to get some data back from the server at the same time.
$('<%=escape_javascript #my_params.to_json%>');
$("#partial").html('<%= escape_javascript(render partial: "view/partial" )%>');
gives me the response with both data and partial rendering in it, but it breaks the Ajax render, so the partial is not rendered.
Using Rails 4, ROR. no errors in the browser or Rails
if i refresh the page i get the result i wanted.
I know this must be easier than i'm making it.
Assuming that you are using js.erb format for rendering ajax page.
Inside the view partial, write the code
run your js code here or assign to global js variable
I'll leave this here for edification, but my friends told me that they would disavow me if i abused a cookie this way. So i switched my implementation, can't afford to lose any friends. They told me to focus on making the turn around time for the ajax call fast. I still needed to know when the object had completed rendering so i simply added a hidden element in the partial and i set its size to zero and wait until the partial rendering changes the height from zero. It was pretty funny to see the interactions with two tabs open to the web page, even though i was planning to use the session ID avoid crosstalk.
Okay, I decided that for my purposes the best way was to put the data in a cookie and just detect when the cookie changed. This allowed me to change the cookie at the end of the send_data command and both get the data for the image position relative to the other image as well as detect when the send_data completed so i could slide the image into place (over the animated wait image).
it looks like this on the server
send_data(image.to_blob { self.format = 'png' },
type: 'image/png',
disposition: 'inline')
cookies[:duck_data] = { :value => $cookie_data.to_json}
and this on the client side
wait_for_paint=->
if $.cookie('duck_data') == 'keep waiting'
setTimeout (->wait_for_paint()), 250
else
my_data= $.parseJSON($.cookie('duck_data'))
do_ajax_response(my_data)
I am using Ruby on Rails v3.0.9 and I would like to retrieve the favicon.ico image of each web site for which I set a link.
That is, if in my application I set the http://www.facebook.com/ URL I would like to retrieve the Facebook' icon and use\insert that in my web pages. Of course I would like to do that also for all other web sites.
How can I retrieve favicon.ico icons from web sites in an "automatic" way (with "automatic" I mean to search for a favicon in a web site and get the link to it - I think no because not all web sites have a favicon named exactly 'favicon.ico'. I would like to recognize that in an "automatic" way)?
P.S.: What I would like to make is something like Facebook makes when to add a link\URL in your Facebook page: it recognizes the related web site logo and then appends that to the link\URL.
http://getfavicon.appspot.com/ works great for fetching favicons. Just give it the url for the site and you'll get the favicon back:
http://g.etfv.co/http://www.google.com
Recently I have written some similar solution.
If we want find favicon url, that can be not only .ico file and can be not in the root, we should parse target site html.
In Ruby on Rails, I have used nokogiri gem for html parsing.
First we parse all meta tags where itemprop attribute contains image keyword. It is necessary in situations where target site used https://schema.org/WebPage template, that more modern technology than just link tag.
If we found it, we can use content attribute as favicon url. But we should check it for really URL existence, just to be sure.
If we can't found some meta tags, then we search for standard link tags, where rel attribute contains icon keyword. This is W3C standard situation (https://www.w3.org/2005/10/howto-favicon)
And some code of my solution:
require 'open-uri'
def site_icon_link site
icon_link = nil
url = nil
doc = Nokogiri::HTML(open(site))
metas = doc.css("meta[itemprop*=image]")
if metas.any?
url = metas.first.attributes['content'].value
else
links = doc.css("link[rel*=icon]")
if links.any?
url = links.first.attributes['href'].value
end
end
if url =~ URI::regexp
icon_link = url
elsif (site + url) =~ URI::regexp
icon_link = site + url
end
icon_link
end
The favicons are being found by two ways. First, there is a 'hardcoded', traditional name of `http://example.com/favicon.ico'.
Second, the HTML pages may define the favicon in their <head> sections, by <link rel="icon"...> and a few other. (You may want to read the Wikipedia article about favicon)
So, your automat may fetch the main page of given website, parse it and check whether there are proper <link> tags, and then, as a fallback, try the "hardcoded" favicon.ico name.
I think I missed your question ...
you want to grab a favicon from another site and make it yours?
if that's what you want, you can get directly from the home icon and save it in your public folder.
thus: www.facebook.com favicon: www.facebook.com/favicon.ico
take that image and save with the name favicon in your public folder
done it should be sufficient
if you want it dinamicaly you can use jquery, but if you want that static you can put a image tag pointing to: [root url of the website]/favicon.ico
like this: <%= image_tag "#{website.url}/favicon.ico" %>
With javascript (jQuery), like this: http://jsfiddle.net/aX8T4/
Can't you just use a regular img tag with the src attribute pointing to the favicon?
<img src="http://www.facebook.com/favicon.icon">
This assumes a browser recognizes a .ico file as an image. Helped methods would probably work with this too.
You can do it easily with pismo gem.
Quick example to get the url of Facebook's favicon:
Pismo::Document.new('http://www.facebook.com/').favicon
Here's my ruby method, that will strip the end off a URL, append the favicon, and produce an image tag.
def favicon_for(url)
matches = url.match(/[^:\/]\/(.*)/)
image_tag url.sub(matches[1], '') + '/favicon.ico', {width: '16px', height: '16px'}
end
There are lots of questions about how to force the browser to cache or not to cache any image. But, I am facing slightly different situation. In several places of my web page, I am using following code for the images.
<img title="<%= Html.Encode(Model.title)%>"
src="<%= Url.Action(MVC.FrontEnd.Actions.RetrieveImage(Model.SystemId))%>"/>
So, in the generated HTML it is like
<img title="blahblah" src="http://xyz.com/FrontEnd/Actions/RetrieveImage?imageId=X">
Where X is some integer. I have seen that though the browser (IE or Mozilla) caches images by default, it is not caching images generated by above method.
Is there any way I can tell browser to cache images of above type?
Thanks in advance.
In order to do this you can set the Expires and MaxAge headers of the response. To simplify things, you can create a custom ActionFilter.
Here's a good guide in how to achieve this: ASP.NET MVC Action Filter - Caching and Compression