27

I don't know if this is possible or not, I have an image host that I've made myself. I need some last tweaks with it.

Whenever an image has been deleted or is an invalid image url, it should replace with an 404 image, so for example if someone adds this:

http://imagehosturl.com/i/34njk5n.jpg

But it's an invalid link, so I need it to show:

http://imagehosturl.com/img/notfound.jpg

Which is like this:

alt text http://tinypic.com/images/404.gif

I do know that .htaccess can do this with it's ErrorDocument 404, but I have one already when a user access to an invalid page, so it would show the 404 page.

So whenever a user hotlinks an image and it's invalid or is deleted, I need it to be replaced with the 404 image.

How can I make this?

MacMac
  • 34,294
  • 55
  • 151
  • 222
  • You could try modifying your `.htaccess` to throw a `404 page` for all missing files **except** image files, which would get your `404 image` instead. – drudge Oct 25 '10 at 18:07

5 Answers5

46

Here's one potential answer:

RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule \.(gif|jpe?g|png|bmp) /path/to/logo.gif [NC,L]

Another is to use a custom scripted page:

Use the errorDocument directive (documented at [httpd.apache.org ]) to point a '404' error to a script (perl, PHP, whatever). If the requested file has an image extension (or has an image/* mimetype; PHP supplies the mime_content_type [us2.php.net] function for this; I'm sure there are many ways to do this in perl; the MIME::Types [search.cpan.org] module is one way), then set the "Content-Type" header to the mimetype of your logo image and return the content of the logoimage to the browser.

http://www.webmasterworld.com/forum92/3458.htm

AdamH
  • 1,378
  • 9
  • 10
  • The first one worked, just tweaked it as said from that link, so it works perfectly. Thanks. – MacMac Oct 25 '10 at 18:40
  • Just in case the link changes or becomes unavailable, it looks like this has already been done in the answer: "Note: there needs to be a space before the '!', and all '¦' characters need to be solid pipes, not broken ones" – jsims281 Jun 22 '12 at 11:25
  • 1
    Definitely best to send to a script instead of to an image, because just sending it to the image this way doesn't send a `404` header. If you send it to a script, the script can output both the `404` header and the image itself, giving you the best of both worlds. – brentonstrine Apr 30 '15 at 21:42
  • loved the 'jpe?g' solution! :) – Rafael Moni Dec 21 '15 at 11:34
  • 1
    This solution doesn't preserve the 404 status code. – reinierpost Sep 04 '17 at 13:16
24
<FilesMatch ".(jpg|png|gif)$">
ErrorDocument 404 "/path/to/image.jpg"
</FilesMatch>
ditto
  • 5,917
  • 10
  • 51
  • 88
  • Nice solution. It's simple, retains the 404 header, and doesn't require having your images all in one folder. – aNoble Oct 29 '12 at 23:08
  • It works! Actually I don't know if you should put "" near 404 : [here](http://httpd.apache.org/docs/2.4/custom-error.html) apache say: the action will be treated as: * A local URL to redirect to (if the action begins with a "/"). * An external URL to redirect to (if the action is a valid URL). * Text to be displayed (if none of the above). The text must be wrapped in quotes (") if it consists of more than one word. – Paolo Biavati May 13 '15 at 17:02
  • 1
    This is the best, very elegant solution! – duy Apr 14 '18 at 06:44
21

With Apache, you can have multiple .htaccess files. So, if all of your images are stored in the same directory, create an .htaccess file inside of that directory and add

ErrorDocument 404 /img/notfound.jpg

This will create a custom 404 redirect that is applied only to your image directory, plus its subdirectories.

Garrett Hyde
  • 5,409
  • 8
  • 49
  • 55
6

You can use ErrorDocument with FilesMatch directive

<filesMatch "\.(jpg|png|gif)$">
ErrorDocument 404 /image.jpg 
</filesMatch>

This will show /image.jpg if a 404 image uri with jpg png or gif extension is requested.

you can also add your custom image or html markup to the errordocument :

<filesMatch "\.(jpg|png|gif)$">
ErrorDocument 404 '<img src="image.jpg">'
</filesMatch>
Amit Verma
  • 40,709
  • 21
  • 93
  • 115
2

According and in addition to AdamH's answer, you should output 404 header. Here's what I'm using,

.htaccess

RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule \.(gif|jpe?g|png|bmp) /upload/image404.php [NC,L]

image404.php

<?php
    $file = 'image404.jpg';
    $type = 'image/jpeg';
    header("HTTP/1.0 404 Not Found");
    header('Content-Type:'.$type);
    header('Content-Length: ' . filesize($file));
    readfile($file);
?>
Bhavesh G
  • 3,000
  • 4
  • 39
  • 66