如何在Nginx配置中实现URL重定向/重写到同一PHP文件?
Fixing Nginx Redirect/Rewrite Issues: Step-by-Step Guide
Hey there! Let's work through your Nginx redirect/rewrite problems—this is a super common pain point, so I'll break down exact implementations, key pitfalls, and testing tips to get your rules working as expected.
1. Start with the return Directive (Preferred for Simple Redirects)
The return directive is more efficient than rewrite for straightforward redirects, so use this first whenever possible. It supports both permanent (301) and temporary (302) redirects.
Example 1: Redirect an Entire Domain
server { listen 80; server_name old.example.com; # Redirect all traffic to the new domain, preserving protocol and original path return 301 $scheme://new.example.com$request_uri; }
Example 2: Redirect a Specific Path
location /old-checkout { # Temporary redirect to the new checkout page return 302 /new-checkout; }
$schemeautomatically useshttporhttpsbased on the incoming request$request_uripreserves the original path and query parameters (e.g.,/old-path?foo=barbecomes/new-path?foo=bar)
2. Use rewrite for Complex Pattern Matching
When you need regex-based matching (like dynamic URLs), use the rewrite directive. Its syntax is:
rewrite regex replacement [flag];
Example 1: Rewrite Dynamic Article URLs
location /archive { # Match /archive/123 and redirect to /blog/post-123 rewrite ^/archive/(\d+)$ /blog/post-$1 permanent; }
Example 2: Rewrite URLs with Query Parameters
location /shop { # Match /shop?product_id=456 and rewrite to /products/456 rewrite ^/shop$ /products/$arg_product_id? last; }
Key Flags to Know:
permanent: Sends a 301 (permanent) redirect (cached by browsers)redirect: Sends a 302 (temporary) redirectlast: Stops processing current rules and re-matches the new URI against all server/location blocksbreak: Stops processing all subsequent rules in the current location block
3. Why Your Rules Might Not Be Working (Common Pitfalls)
If your redirects/rewrites aren’t taking effect, check these first:
- Wrong Configuration Block: Make sure your rules are in the correct
serverblock (e.g., if using HTTPS, rules need to be in thelisten 443 sslblock, not thelisten 80block). - Regex Mistakes: Forgetting anchors (
^= start of string,$= end of string) can cause over-matching or no matching at all. For example,rewrite /archive /blogwill match any URL containing/archive, while^/archive$only matches the exact/archivepath. - Browser Caching: 301 redirects are cached aggressively by browsers. Test in incognito mode, clear your cache, or use
curlto bypass browser caching. - 未重载配置: After editing your Nginx config, run
sudo nginx -tto validate syntax, thensudo nginx -s reloadto apply changes. Ifnginx -tthrows errors, your config won’t reload. - Location Priority Conflicts: Nginx matches locations in this order:
- Exact matches (
location = /path) - Prefix matches with
^~ - Case-sensitive regex matches (
~) - Case-insensitive regex matches (
~*) - Regular prefix matches
If a higher-priority location is handling your request, your rewrite/redirect rule won’t trigger.
- Exact matches (
4. Test Your Rules Effectively
- Use
curlto Debug: Runcurl -v http://your-domain.com/old-pathto see the full request/response cycle. Look for theLocationheader to confirm the redirect target. - Check Nginx Logs: Review
/var/log/nginx/access.logto see if your request is hitting the right location block, and/var/log/nginx/error.logfor any syntax or runtime errors.
Full Working Example
Here’s a complete config that handles domain redirects, path redirects, and dynamic rewrites:
server { listen 80; server_name old.example.com www.old.example.com; # Redirect HTTP traffic to HTTPS on the new domain return 301 https://new.example.com$request_uri; } server { listen 443 ssl; server_name new.example.com; # SSL certificate config (omitted for brevity) ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; # Exact path redirect location = /old-about { return 301 /about-us; } # Dynamic rewrite for blog posts location /legacy-blog { rewrite ^/legacy-blog/(\d+)-(\w+)$ /articles/$2?post_id=$1 permanent; } # Serve your main site content location / { root /var/www/your-site; index index.html index.php; } }
内容的提问来源于stack exchange,提问作者edward.




