如果 URL 请求路径与某些模式匹配,我会尝试重写/重定向到特定子域。
如果我收到类似这样的请求,我想做这样的事情“https://example.com/users/john/likes“我想以此作为”https://john.example.com/likes“
以下是迄今为止尝试过的方法:我可以创建如下位置
`location ~ ^/users { #TODO: some magic }`
尝试了很多方法使用正则表达式来捕获 uri 的“john”部分,但是没有成功,正则表达式中的很新,有什么想法可以实现它吗?
更新:正如答案中指出的那样,我需要满足来自 nginx conf 的请求,这是我正在使用的配置,请注意,我在子域下测试它:
server {
listen 80;
server_name staging.example.com;
return 301 https://staging.example.com$request_uri;
}
map $name $uri_prefix {
~(.+)$ /users/$1;
}
# This is the new server block I created which will serve the subdomain requests I think i can write conditions in one server block
server {
listen 443 ssl;
server_name ~^(?<name>[^\.]+)\.example\.com$;
client_max_body_size 1000m;
add_header X-UA-Compatible "IE=Edge,chrome=1";
root /home/something/app/;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
ssl_certificate /etc/nginx/ssl/app.crt;
ssl_certificate_key /etc/nginx/ssl/app.key;
error_page 500 502 503 504 /500.html;
location / {
try_files $uri @prerender;
}
location @prerender {
set $prerender 0;
if ($http_user_agent ~* "googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
set $prerender 1;
}
if ($args ~ "_escaped_fragment_") {
set $prerender 1;
}
if ($http_user_agent ~ "Prerender") {
set $prerender 0;
}
if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
set $prerender 0;
}
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8;
if ($prerender = 1) {
#setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
set $prerender "staging-render.example.com:3000";
rewrite .* /$scheme://$host$request_uri? break;
proxy_pass http://$prerender;
}
if ($prerender = 0) {
rewrite ^(.*)$ $uri_prefix$1;
}
}
}
server {
listen 443 ssl;
server_name staging.example.com;
client_max_body_size 1000m;
add_header X-UA-Compatible "IE=Edge,chrome=1";
root /home/something/app/;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
ssl_certificate /etc/nginx/ssl/app.crt;
ssl_certificate_key /etc/nginx/ssl/app.key;
error_page 500 502 503 504 /500.html;
location / {
try_files $uri @prerender;
}
location = /sitemap.xml.gz {
root /home/ubuntu/site_maps;
}
location @prerender {
set $prerender 0;
if ($http_user_agent ~* "googlebot|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
set $prerender 1;
}
if ($args ~ "_escaped_fragment_") {
set $prerender 1;
}
if ($http_user_agent ~ "Prerender") {
set $prerender 0;
}
if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
set $prerender 0;
}
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8;
if ($prerender = 1) {
#setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
set $prerender "staging-render.example.com:3000";
rewrite .* /$scheme://$host$request_uri? break;
proxy_pass http://$prerender;
}
if ($prerender = 0) {
rewrite .* /index.html break;
}
}
}
答案1
如果您想要接收具有此类 URI 的 HTTP 重定向,请尝试以下操作:
server {
...
server_name www.example.com example.com;
...
location ~ ^/users/([^/]+)(.*)$ {
return 301 $scheme://$1.example.com$2;
}
...
}
但是你的问题不清楚,你是否也需要用 nginx 配置来为这些子域名提供服务?这可以通过一个额外的server
块来完成:
map $name $uri_prefix {
~(.+)$ /users/$1;
}
server {
...
server_name ~^(?<name>[^\.]+)\.example\.com$;
...
rewrite ^(.*)$ $uri_prefix$1; # do an internal URI rewriting not visible to the end user
...
# process a rewrited request (now in the form "/users/username/...")
}
不要尝试将这两个server
块合并为一个,否则您将收到无限循环。
答案2
您可以尝试以下 nginx 规则:
if ($request_uri ~* "^/users/(.*)/(.*)"){
return 301 hhttps://$1.example.com/$2;
}