为什么这个看似无关紧要的 IF 块会导致问题?

问题描述

我们有一个 Laravel 安装,用于运行同一网络应用程序的多个克隆,但基于域名的内容略有不同。

今天我的任务是基于当前的 HTTP_HOST(域名)提供不同的 sitemap.xml

所以我创建了一个响应 /sitemap.xml 的路由,然后根据当前的 $_SERVER['HTTP_HOST'] 从正确的文件夹中提供一个 sitemap.xml。 Easy peasy.. 在我的本地主机上完美运行.. 10 分钟内完成!

然后我花了 4 个小时对 Nginx 进行故障排除..

在生产环境中,无论如何点击 /sitemap.xml 都会返回 404。

我将其缩小到 Nginx 配置并想出了如何解决它.. 但我不明白为什么它会导致问题开始。我们使用 rendertron(类似于 prerender.io)为搜索引擎爬虫提供预渲染页面rendertron 块中的某些内容导致了冲突。让我告诉你:

所以,首先.. 如果我不包括 rendertron 块而只使用:

  location / {
    try_files $uri $uri/ /index.PHP?$args;
  }

然后它工作得很好

这是导致问题的 Nginx 配置的实际部分:

  location / {
      try_files $uri @prerender;
  }

  location @prerender {
      
      set $prerender 0;

      if ($http_user_agent ~* "googlebot|yahoo|bingbot|yandex|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest\/0\.|pinterestbot|slackbot|discordbot|vkShare|W3C_Validator|whatsapp|duckduckbot") {
          set $prerender 1;
      }
      if ($args ~ "_escaped_fragment_|prerender=1") {
          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 "{{ item.value.prerenderer }}";
          rewrite .* /render/$scheme://$host$request_uri break;
          proxy_pass https://$prerender;
      }
      
      try_files $uri $uri/ /index.PHP?$args;
  }

现在让我们暂时忽略读取 sitemap.xml 的机器人可能会或可能不会在上面的列表中存在用户代理。就我而言,我只是使用常规用户代理访问 /sitemap.xml 路由,因此显然没有预渲染任何内容,因为它不应该是,但它仍然导致 404。set $prerender 1;因此不会被触发,它不会尝试为我提供一个预渲染的页面,它应该只是点击该条件块的底部并点击 try_files $uri $uri/ /index.PHP?$args; 并以我的快乐方式发送给我。但不知何故它正在崩溃。

冲突的原因似乎是

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

如果我从这个列表中删除 xml,那么问题就完全消失了。但为什么?为什么这个 IF 块会导致 set $prerender 0;,这应该完全无关紧要,因为此时 $prerender 已经设置为 0,导致我出现这些问题?

现在我刚刚从列表中删除xml,但现在我很担心,我真的不希望 xml 被缓存/预渲染。我还想了解一些关于为什么 Nginx 在这种情况下表现得很奇怪的新东西。

有人解释一下吗?也许一个适当的修复可以让我添加 xml 而不会遇到 404s

非常感谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...