我有一个 SPA 网站,我需要<meta>
为每个子页面加载适当的标签,但从子页面本身来看并不容易,所以我创建了一个单独的地址,Facebook 或 Twitter 机器人可以在那里下载适当的 OpenGraph 值。它看起来像这样:
原始网址:http://website.com/contents/1
此 URL 带有 OG 标签的路由:http://website.com/og/contents/1
我想proxy_pass
为此使用,只考虑特定的User-Agent
,但是以下配置不起作用,即没有重定向:
location /contents {
resolver 127.0.0.11 ipv6=off valid=5m;
if ($http_user_agent ~* ("(facebookexternalhit)\/(.*)|(Twitterbot)\/(.*)")) {
proxy_pass http://$host:8080/open-graph$request_uri;
}
}
有谁看到哪里不好吗?
答案1
首先,当你需要在 nginx 配置中使用一些字符串时,你可以使用单引号或双引号,或者根本不使用它们(除非你的字符串包含一些特殊字符,如空格、花括号等)。在你的情况下,nginx 假定你不使用任何引号(因为你的字符串以圆括号开头),因此 nginx 处理的正则表达式字符串("(facebookexternalhit)\/(.*)|(Twitterbot)\/(.*)")
包括圆括号和双引号。除非它包含"facebookexternalhit/..."
或"twitterbot/..."
子字符串,否则它不会匹配任何用户代理用双引号。
其次,您不需要那么多捕获(事实上您根本不需要它们,因为您以后不会使用它们)。这些捕获使 nginx 在将字符串与正则表达式匹配时花费一些额外的资源(这不是您在高负载系统上想要的)。以下块应该按预期工作(请注意,符号不需要/
转义,尽管转义它不会破坏正则表达式):
if ($http_user_agent ~* (facebookexternalhit|twitterbot)/) {
proxy_pass http://$host:8080/open-graph$request_uri;
}
然而,这不是一个好的解决方案。最好避开if
建筑物除非你只使用ngx_http_rewrite_module
块内的指令if
。在我们的例子中,nginx 将创建两个配置 - 如果 User-Agent 字符串与正则表达式匹配,则将使用第一个配置,如果不匹配,则将使用第二个配置。我强烈建议不要if
在这里使用构造。您可以使用map
改为翻译:
map $http_user_agent $og_prefix {
~*(facebookexternalhit|twitterbot)/ /open-graph;
}
server {
...
location /contents {
resolver 127.0.0.11 ipv6=off valid=5m;
proxy_pass http://$host:8080$og_prefix$request_uri;
}
...
}
如果 User-Agent 字符串与正则表达式匹配,则变量的值$og_prefix
将为空字符串。/open-graph