我有一个正在运行的网站http://www.example.com
(使用 PHP-FPM),我想将其所有传入流量重定向到另一个网站(ttps://www.other-example.com/foo.html
)上的 URL,除了一个特定路径(/api
)。
下面是我尝试过的 Nginx 配置(将 PHP 处理内容放在专用的location
for/api
和return 301
on 中location /
):
upstream php {
server unix:/var/run/php/php7.4-fpm.sock;
}
server {
listen 80;
listen [::]:80;
server_name www.example.com;
root /var/www/www.example.com;
index index.php;
location ~ ^/api(?:/(.*))?$ {
#return 418;
try_files $uri $uri/ /index.php$is_args$args;
location ~ \.php$ {
#include snippets/fastcgi-php.conf;
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi.conf;
include fastcgi_params;
fastcgi_pass php;
}
}
location / {
return 301 https://www.other-example.com/foo.html;
}
}
但是我的所有请求(http://www.example.com
,http://www.example.com/foo
和http://www.example.com/api
)都得到HTTP/1.1 301 Moved Permanently
了Location: https://www.other-example.com/foo.html
。
我知道这些location ~ ^/api(?:/(.*))?$
工作原理,因为如果我取消注释,return 418;
我会得到 418 个http://www.example.com/api
请求响应,但其他请求则会得到 301 个响应。
答案1
在您的情况下,nginx 处理如下:
- 请求
/api/test_endpoint
匹配该location ~ ^/api(?:/(.*))?$
块。 - 在 中
try_files
,它匹配/index.php$is_args$args
部分。由于它是最后一部分,因此会触发内部重定向。 - nginx 使用 uri 重新启动处理
/index.php
。这将匹配location /
触发重定向的块。
解决该问题的一个解决方案是以下配置:
location ~ ^/api(?:/(.*))?$ {
#return 418;
try_files $uri $uri/ /index.php$is_args$args;
}
location / {
return 301 https://www.other-example.com/foo.html;
}
location = /index.php {
internal;
#include snippets/fastcgi-php.conf;
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi.conf;
include fastcgi_params;
fastcgi_pass php;
}
index.php
通过此配置,nginx在请求处理的第 3 步中找到匹配项。internal
关键字阻止外部请求/index.php
匹配此块。外部请求将由块/index.php
提供服务。location /