可以在Nginx中循环遍历块并使用变量吗?

huangapple go评论81阅读模式
英文:

Is it possible to loop over blocks in Nginx and use variables?

问题

我想要做的是将传入 URL 的 /locale/ 部分替换为等效的查询字符串。我想在我的反向代理中实现这个功能,使用的是 Nginx。

考虑以下 Nginx 代码:

  1. include /etc/letsencrypt/options-ssl-nginx.conf;
  2. ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  3. location /
  4. {
  5. proxy_pass http://localhost:3500;
  6. }
  7. location = /fa
  8. {
  9. proxy_pass http://localhost:3500;
  10. rewrite ^/fa/(.*)$ /$1?locale=fa;
  11. rewrite ^/fa /?locale=fa;
  12. }
  13. location /fa/
  14. {
  15. proxy_pass http://localhost:3500;
  16. rewrite ^/fa/(.*)$ /$1?locale=fa;
  17. rewrite ^/fa /?locale=fa;
  18. }
  19. location = /en
  20. {
  21. proxy_pass http://localhost:3500;
  22. rewrite ^/en/(.*)$ /$1?locale=en;
  23. rewrite ^/en /?locale=en;
  24. }
  25. location /en/
  26. {
  27. proxy_pass http://localhost:3500;
  28. rewrite ^/en/(.*)$ /$1?locale=en;
  29. rewrite ^/en /?locale=en;
  30. }
  31. location = /ar
  32. {
  33. proxy_pass http://localhost:3500;
  34. rewrite ^/ar/(.*)$ /$1?locale=ar;
  35. rewrite ^/ar /?locale=ar;
  36. }
  37. location /ar/
  38. {
  39. proxy_pass http://localhost:3500;
  40. rewrite ^/ar/(.*)$ /$1?locale=ar;
  41. rewrite ^/ar /?locale=ar;
  42. }
  43. location = /ru
  44. {
  45. proxy_pass http://localhost:3500;
  46. rewrite ^/ru/(.*)$ /$1?locale=ru;
  47. rewrite ^/ru /?locale=ru;
  48. }
  49. location /ru/
  50. {
  51. proxy_pass http://localhost:3500;
  52. rewrite ^/ru/(.*)$ /$1?locale=ru;
  53. rewrite ^/ru /?locale=ru;
  54. }
  55. location = /tr
  56. {
  57. proxy_pass http://localhost:3500;
  58. rewrite ^/tr/(.*)$ /$1?locale=tr;
  59. rewrite ^/tr /?locale=tr;
  60. }
  61. location /tr/
  62. {
  63. proxy_pass http://localhost:3500;
  64. rewrite ^/tr/(.*)$ /$1?locale=tr;
  65. rewrite ^/tr /?locale=tr;
  66. }

正如您所看到的,许多代码都是重复的,包括位置块、正则表达式和 proxy_pass 指令等。我想要能够使这一部分更加干燥(Don't Repeat Yourself)。

基本上,每个区域都重复了以下部分:

  1. location = /tr
  2. {
  3. proxy_pass http://localhost:3500;
  4. rewrite ^/tr/(.*)$ /$1?locale=tr;
  5. rewrite ^/tr /?locale=tr;
  6. }
  7. location /tr/
  8. {
  9. proxy_pass http://localhost:3500;
  10. rewrite ^/tr/(.*)$ /$1?locale=tr;
  11. rewrite ^/tr /?locale=tr;
  12. }

是否有一种方法可以循环处理各个区域,而不重复这个部分呢?

英文:

What I want to do is to replace the /locale/ part of the incoming URL with an equivalent query string. I want to do this in my reverse proxy which is Nginx.

Consider this Nginx code:

  1. include /etc/letsencrypt/options-ssl-nginx.conf;
  2. ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  3. location /
  4. {
  5. proxy_pass http://localhost:3500;
  6. }
  7. location = /fa
  8. {
  9. proxy_pass http://localhost:3500;
  10. rewrite ^/fa/(.*)$ /$1?locale=fa;
  11. rewrite ^/fa /?locale=fa;
  12. }
  13. location /fa/
  14. {
  15. proxy_pass http://localhost:3500;
  16. rewrite ^/fa/(.*)$ /$1?locale=fa;
  17. rewrite ^/fa /?locale=fa;
  18. }
  19. location = /en
  20. {
  21. proxy_pass http://localhost:3500;
  22. rewrite ^/en/(.*)$ /$1?locale=en;
  23. rewrite ^/en /?locale=en;
  24. }
  25. location /en/
  26. {
  27. proxy_pass http://localhost:3500;
  28. rewrite ^/en/(.*)$ /$1?locale=en;
  29. rewrite ^/en /?locale=en;
  30. }
  31. location = /ar
  32. {
  33. proxy_pass http://localhost:3500;
  34. rewrite ^/ar/(.*)$ /$1?locale=ar;
  35. rewrite ^/ar /?locale=ar;
  36. }
  37. location /ar/
  38. {
  39. proxy_pass http://localhost:3500;
  40. rewrite ^/ar/(.*)$ /$1?locale=ar;
  41. rewrite ^/ar /?locale=ar;
  42. }
  43. location = /ru
  44. {
  45. proxy_pass http://localhost:3500;
  46. rewrite ^/ru/(.*)$ /$1?locale=ru;
  47. rewrite ^/ru /?locale=ru;
  48. }
  49. location /ru/
  50. {
  51. proxy_pass http://localhost:3500;
  52. rewrite ^/ru/(.*)$ /$1?locale=ru;
  53. rewrite ^/ru /?locale=ru;
  54. }
  55. location = /tr
  56. {
  57. proxy_pass http://localhost:3500;
  58. rewrite ^/tr/(.*)$ /$1?locale=tr;
  59. rewrite ^/tr /?locale=tr;
  60. }
  61. location /tr/
  62. {
  63. proxy_pass http://localhost:3500;
  64. rewrite ^/tr/(.*)$ /$1?locale=tr;
  65. rewrite ^/tr /?locale=tr;
  66. }

As you can see, a lot of code is repetitive. This includes the location block and the regex and the proxy_pass directive, etc. I want to be able to DRY this part.

Basically, this part is getting repeated for each locale:

  1. location = /tr
  2. {
  3. proxy_pass http://localhost:3500;
  4. rewrite ^/tr/(.*)$ /$1?locale=tr;
  5. rewrite ^/tr /?locale=tr;
  6. }
  7. location /tr/
  8. {
  9. proxy_pass http://localhost:3500;
  10. rewrite ^/tr/(.*)$ /$1?locale=tr;
  11. rewrite ^/tr /?locale=tr;
  12. }

Is there a way to loop over locales and not repeat this section?

答案1

得分: 2

rewrite语句可以在正则表达式中捕获区域设置,例如:

  1. rewrite ^/(\w\w)/(.*)$ /$2?locale=$1 break;
  2. rewrite ^/(\w\w)$ /?locale=$1 break;

使用正则表达式选择任何带有区域设置的URI,例如:

  1. location ~ ^/(fa|en|ar|ru|tr)(/|$) { ... }

或更一般地(如果适用于您):

  1. location ~ ^/\w\w(/|$) { ... }

示例:

  1. location / {
  2. proxy_pass http://localhost:3500;
  3. }
  4. location ~ ^/\w\w(/|$) {
  5. rewrite ^/(\w\w)/(.*)$ /$2?locale=$1 break;
  6. rewrite ^/(\w\w)$ /?locale=$1 break;
  7. proxy_pass http://localhost:3500;
  8. }
英文:

The rewrite statements can capture the locale in the regular expression, for example:

  1. rewrite ^/(\w\w)/(.*)$ /$2?locale=$1 break;
  2. rewrite ^/(\w\w)$ /?locale=$1 break;

Use a regular expression to select any URI with a locale, for example:

  1. location ~ ^/(fa|en|ar|ru|tr)(/|$) { ... }

Or more generally (if this works for you):

  1. location ~ ^/\w\w(/|$) { ... }

Example:

  1. location / {
  2. proxy_pass http://localhost:3500;
  3. }
  4. location ~ ^/\w\w(/|$) {
  5. rewrite ^/(\w\w)/(.*)$ /$2?locale=$1 break;
  6. rewrite ^/(\w\w)$ /?locale=$1 break;
  7. proxy_pass http://localhost:3500;
  8. }

huangapple
  • 本文由 发表于 2023年6月2日 14:00:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76387485.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定