image unreadable on codeigniter site?

2019-05-28 10:45发布

问题:

(This may belong on serverfault, since apache is causing the error; please move if necessary.)

I have a CodeIgniter site that I'm trying to display an image in. My image is stored in the ignite/application/images folder (where ignite is actually the root install of CodeIgniter), and here's my code:

 <td><img src="<?php echo base_url(); ?>application/images/unrav.png" /></td>

The rendered source produces the following URL:

<td><img src="http://localhost/ignite/application/images/unrav.png" /></td> 

This SHOULD work, but it's not displaying the image, and when I go to the URL directly, I get the following error:

Access forbidden!

You don't have permission to access the requested object. It is either read-protected or not readable by the server.

If you think this is a server error, please contact the webmaster.

Error 403

localhost
Sun 20 Feb 2011 04:31:02 PM CST
Apache/2.2.14 (Unix) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1

I've checked the image permissions and set them to 777 (read, write, execute for owner, group, and public). This is on my local dev server, and if I go a File/Open in my browser and navigate through the file system to the image, it does display correctly, so I know the image isn't corrupted or anything. Can anyone give me an idea of what's happening? I've strictly done development up to this point, no server admin, so I'm not at all familiar with what apache's problem is.

EDITED to add apache error log:

[Sun Feb 20 16:26:07 2011] [error] [client 127.0.0.1] client denied by server configuration: /opt/lampp/htdocs/ignite/application/images/unrav.png

EDITED AGAIN to add .htaccess:

RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
aRewriteRule ^(.*)$ /index.php/$1 [L]

EDITED YET AGAIN to add apache log after adding RewriteBase:

[Sun Feb 20 17:02:19 2011] [notice] suEXEC mechanism enabled (wrapper: /opt/lampp/bin/suexec)
[Sun Feb 20 17:02:19 2011] [warn] RSA server certificate is a CA certificate (BasicConstraints: CA == TRUE !?)
[Sun Feb 20 17:02:19 2011] [warn] RSA server certificate CommonName (CN) `localhost' does NOT match server name!?
[Sun Feb 20 17:02:19 2011] [notice] Digest: generating secret for digest authentication ...
[Sun Feb 20 17:02:19 2011] [notice] Digest: done
[Sun Feb 20 17:02:20 2011] [warn] RSA server certificate is a CA certificate (BasicConstraints: CA == TRUE !?)
[Sun Feb 20 17:02:20 2011] [warn] RSA server certificate CommonName (CN) `localhost' does NOT match server name!?
[Sun Feb 20 17:02:20 2011] [notice] Apache/2.2.14 (Unix) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1 configured -- resuming normal operations

回答1:

My guess is that your .htaccess file isn't set up properly to not rewrite requests for image files. As you're serving CodeIgniter from somewhere other than the server root (i.e. /ignite/) the standard CI .htaccess file probably isn't matching the images folder in order not to rewrite it to point at index.php.

What's in your .htaccess file? Is there a RewriteBase directive? See the mod_rewrite wiki CI entry to see if you can get any clues. Or just try

RewriteBase /ignite/ 

...just after the RewriteEngine On and see what happens.

If it helps understand what's happening, the standard CI .htaccess looks something like this:

RewriteEngine on
RewriteCond $1 !^(index\.php|images|table-images|js|robots\.txt|css)
RewriteRule ^(.*)$ /index.php/$1 [L]

The main event is the RewriteRule, which throws everything that comes in onto the end of the index.php. This is so you don't need to have index.php at the start of your CI URLs, that is, instead of http://www.example.com/index.php/controller/method, you can just write http://www.example.com/controller/method.

It does that by taking everything from the path (^(.*)$) and rewriting it on the end of index.php. The brackets in the pattern ^(.*)$ are a group. Each group gets given a number that you can use to "backreference" it elsewhere using $n. In this case, there's only one group, and you can refer to it elsewhere as $1. So:

RewriteRule ^(.*)$ /index.php/$1 [L]

Means "grab everything (.*) from the beginning (^) to the end ($) of the path, and call it $1 (because it's the first expression in brackets). Then rewrite the path as /index.php/$1", i.e. shove everything on the end of index.php.

Now, that's fine for most things -- all the controllers and methods -- but if you've got some static files you want to serve, like images, you don't want to go through your controllers, i.e. your index.php. It's a lot faster just to serve them up without going through PHP at all.

That's where the RewriteCond comes in. In this case:

RewriteCond $1 !^(index\.php|images|table-images|js|robots\.txt|css)

...what we're saying is, "only run the following RewriteRule if the first group in its pattern (again, $1) doesn't (!) begin (^) with the following list of things: "index.php", "images", "table-images", "js", "robots.txt", or "css".

And that's how images get served -- instead of the URLs being rewritten by the RewriteRule as if there were a call to a controller, like everything that goes through index.php, they're ignored because the RewriteCond effectively says "don't bother rewriting any paths that start with 'images'", and then served by Apache as normal.

Hope this helps you get to grips with what's going on in the .htaccess.