Nginx

Nginx 使用 URL 路徑動態創建子域

  • June 25, 2020

如果 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;
   }
 }
}

如果您想接收帶有此類 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塊合二為一,否則你會收到一個無限循環。

引用自:https://serverfault.com/questions/946177