Nginx 代理或重写取决于用户代理
Posted
技术标签:
【中文标题】Nginx 代理或重写取决于用户代理【英文标题】:Nginx proxy or rewrite depending on user agent 【发布时间】:2012-05-24 13:12:27 【问题描述】:我是 nginx 新手,来自 apache,我基本上想做以下事情:
基于用户代理: iPhone:重定向到 iphone.mydomain.com
android:重定向到 android.mydomain.com
facebook:反向代理到 otherdomain.com
所有其他:重定向到 ...
并尝试了以下方式:
location /tvoice
if ($http_user_agent ~ iPhone )
rewrite ^(.*) https://m.domain1.com$1 permanent;
...
if ($http_user_agent ~ facebookexternalhit)
proxy_pass http://mydomain.com/api;
rewrite /tvoice/(.*) http://mydomain.com/#!tvoice/$1 permanent;
但是现在我在启动 nginx 时遇到错误:
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except"
我不知道该怎么做或问题出在哪里。
谢谢
【问题讨论】:
【参考方案1】:proxy_pass 目标的“/api”部分是错误消息所指的 URI 部分。由于 ifs 是伪位置,并且带有 uri 部分的 proxy_pass 将匹配的位置替换为给定的 uri,因此在 if 中是不允许的。如果你只是颠倒 if 的逻辑,你可以让它工作:
location /tvoice
if ($http_user_agent ~ iPhone )
# return 301 is preferable to a rewrite when you're not actually rewriting anything
return 301 https://m.domain1.com$request_uri;
# if you're on an older version of nginx that doesn't support the above syntax,
# this rewrite is preferred over your original one:
# rewrite ^ https://m.domain.com$request_uri? permanent;
...
if ($http_user_agent !~ facebookexternalhit)
rewrite ^/tvoice/(.*) http://mydomain.com/#!tvoice/$1 permanent;
proxy_pass http://mydomain.com/api;
【讨论】:
【参考方案2】:这不是最好的方法,因为if is devil
以下是正确的做法。
在http
上创建一个map
:
map $http_user_agent $proxied_server
# anything not matching goes here
default default_domain;
# case sensitive matching
~ (UserAgent) another_domain;
# case INsensitive matching
~* (useragent) third_domain;
# multiple user agents
~* (user|agent|here) forth_domain;
然后,在您的 server
块中:
proxy_pass http://$proxied_server
【讨论】:
以上是关于Nginx 代理或重写取决于用户代理的主要内容,如果未能解决你的问题,请参考以下文章