admin管理员组

文章数量:1391748

I'm trying to adapt the rewrite rule given in Develop Locally, Use Images from Production to do the very same thing on my local dev site (which runs on XAMPP).

This is how the development site's .htaccess looks, with the snippet added towards the end of it (URL replaced with example equivalent, obviously):

<IfModule mod_php.c>
php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300
php_value max_input_time 300
</IfModule>

#START WORDPRESS

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /wordpress/

# Redirect About and Library to first sub page 
RewriteRule ^about/?$ /wordpress/about/history/ [L,NC,R=301]
RewriteRule ^the-library/?$ /wordpress/the-library/gallery/ [L,NC,R=301]

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

# If images not found on development site, load from production 
RewriteCond %{REQUEST_URI} ^/wp-content/uploads/[^\/]*/.*$
RewriteRule ^(.*)$ /$1 [QSA,L]
</IfModule>

#END WORDPRESS

The rewrite rule doesn't seem to be making a difference, whether with the HTTPS or HTTP version of the URL. Images unavailable for the dev site simply don't display, even when the same images load fine for the production site.

I also had no luck trying to adapt the rewrite rule found in this slightly different question applying to Wordpress Multisite.

Additionally, I previously added a filter to stop Wordpress from modifying the .htaccess file, so am pretty sure that this isn't the cause of the problem.

What is wrong with my rewrite rule here that's causing it to fail?

I'm trying to adapt the rewrite rule given in Develop Locally, Use Images from Production to do the very same thing on my local dev site (which runs on XAMPP).

This is how the development site's .htaccess looks, with the snippet added towards the end of it (URL replaced with example equivalent, obviously):

<IfModule mod_php.c>
php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300
php_value max_input_time 300
</IfModule>

#START WORDPRESS

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /wordpress/

# Redirect About and Library to first sub page 
RewriteRule ^about/?$ /wordpress/about/history/ [L,NC,R=301]
RewriteRule ^the-library/?$ /wordpress/the-library/gallery/ [L,NC,R=301]

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

# If images not found on development site, load from production 
RewriteCond %{REQUEST_URI} ^/wp-content/uploads/[^\/]*/.*$
RewriteRule ^(.*)$ https://www.example/$1 [QSA,L]
</IfModule>

#END WORDPRESS

The rewrite rule doesn't seem to be making a difference, whether with the HTTPS or HTTP version of the URL. Images unavailable for the dev site simply don't display, even when the same images load fine for the production site.

I also had no luck trying to adapt the rewrite rule found in this slightly different question applying to Wordpress Multisite.

Additionally, I previously added a filter to stop Wordpress from modifying the .htaccess file, so am pretty sure that this isn't the cause of the problem.

What is wrong with my rewrite rule here that's causing it to fail?

Share Improve this question edited Sep 6, 2019 at 23:41 Hashim Aziz asked Sep 6, 2019 at 20:47 Hashim AzizHashim Aziz 2977 silver badges19 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 3
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

# If images not found on development site, load from production 
RewriteCond %{REQUEST_URI} ^/wp-content/uploads/[^\/]*/.*$
RewriteRule ^(.*)$ https://www.example/$1 [QSA,L]

The problem here is that "If images not found on development site" then the request has already been rewritten to index.php by the preceding RewriteRule (WordPress front-controller), so your rule block that follows does nothing.

NB: Whilst you've not explicitly included the R (redirect) flag on the RewriteRule, this will implicitly trigger an external 302 (temporary) redirect, the same as if you had explicitly included R=302 on the directive. Explicitly including this flag is preferable to more clearly communicate its intent. In fact, you might want to change this to a 301 so that images are cached, thus preventing external redirects to your production server on every request.

The QSA flag is not required here, since you are not including a query string on the RewriteRule susbstitution.

Aside: Your RewriteRule arguably matches too match... it matches everything, not just images, is that intentional?

You could resolve this by either...

  1. preventing all image URLs being processed by the front-controller. For example, add an additional condition to the WP front-controller to exclude images:

    RewriteCond %{REQUEST_URI} !\.(jpe?g|png|gif)$
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . index.php [L]
    
  2. OR, move your redirect to above the WP front-controller, and check for the non-existence of the requested file before redirecting to your production server. I would also be more restrictive on the regex and match only images (as mentioned above) - if that is the intention. For example:

    RewriteRule ^index\.php$ - [L]
    
    # If images not found on development site, load from production
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^wp-content/uploads/[^/]+/.+\.(jpe?g|png|gif)$ https://www.example/$0 [R=302,L]
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . index.php [L]
    

The additional condition is not required, as you can perform the URL comparison in the RewriteRule pattern (more efficient). The slash does not need to be escaped in the character class (or anywhere for that matter). And the QSA flag is not required here (as mentioned above).

Note that the regex matches URL-paths of the form /wp-content/uploads/<somedirectory>/<something>.jpg, where <something> can be any number of additional subdirectories. This is based on your regex.

The $0 backreference (as opposed to $1 in your original directive) is the entire URL-path that is matched by the RewriteRule pattern. $1 contains the first captured subgroup. In the revised directive, the first captured subgroup contains just the image file extension.

本文标签: url rewritingRewrite rule to load images from production does nothing