我是一个SPA(单页应用程序)网站,请在https://example.com下说明,https://api.example.com下的API
我想为googlebot
,facebookexternalhit
等特定用户提供服务器呈现的内容。
因此,如果用户转到https://example.com/brandon/things,它将获得SPA服务,但如果bot转到相同的URL,它将获得服务器呈现的页面,其中包含所有正确的元图和开放图标签。
我的服务器呈现的网页具有正确的匹配位于https://api.example.com/ssr/
下例如,如果机器人点击https://example.com/brandon/things,它应该从https://api.example.com/ssr/brandon/things
获取内容我几乎使用nginx proxy_pass if语句到Django应用程序(它返回服务器渲染输出)但不幸的是有一个边缘情况使它表现得很奇怪。
我的实施:
server {
listen 80;
server_name example.com; # url of SPA
index index.html;
root /srv/example_spa/public/dist; # directory of SPA index.html
# $ssr variable that tells if we should use server side rendered page
set $ssr 0;
if ($http_user_agent ~* "googlebot|yahoo|bingbot|baiduspider|yandex|yeti|yodaobot|gigabot|ia_archiver|facebookexternalhit|facebot|twitterbot|developers\.google\.com|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator|redditbot") {
set $ssr 1;
}
# location block that serves proxy_pass when the $ssr matches
# or if the $ssr doesn't match it serves SPA application index.html
location / {
if ($ssr = 1) {
proxy_pass http://127.0.0.1:9505/ssr$uri$is_args$args;
}
try_files $uri /index.html;
}
}
但问题是:
除了一个案例外,一切都很好看。
用户点击https://example.com/brandon/things/
并获得SPA index.html - 完美。
用户点击https://example.com/brandon/things
并获得SPA index.html - 完美。
Bot点击https://example.com/brandon/things/
并获得服务器呈现页面 - 完美。
Bot点击https://example.com/brandon/things
(没有附加斜线),他被重定向(301)到https://example.com/ssr/brandon/things
- 坏坏了
我已经试着让它工作几个小时而现在没有运气。 你会建议什么?我知道如果在nginx中是邪恶的,但我不知道如何在没有它的情况下使它工作......
感谢任何帮助
答案 0 :(得分:0)
您需要更改proxy_pass
location / {
proxy_redirect http://127.0.0.1/ssr/ http://$host/ssr/;
proxy_redirect /ssr/ /;
if ($ssr = 1) {
proxy_pass http://127.0.0.1:9505/ssr$uri$is_args$args;
}
try_files $uri /index.html;
}
答案 1 :(得分:0)
事实证明这是我的Django应用程序重定向的问题。我以为我有" APPEND_SLASH"选项已禁用,但已启用并在没有斜杠时进行重定向。并且它重定向而不将主机更改为https://api.example.com,但只有URI部分。因此我的困惑。
我实际上找到了两种解决方法。
首先,只有在没有斜线时才使用重写来附加斜杠。
location / {
if ($ssr = 1) {
rewrite ^([^.]*[^/])$ $1/ permanent;
proxy_pass http://127.0.0.1:9505/ssr$uri$is_args$args;
}
try_files $uri /index.html;
}
第二次,修改proxy_pass,以便在$ uri部分和服务器端渲染应用程序url config之后始终添加/斜杠,以在最后接受两个斜杠//'。它有点hacky但没有任何副作用,并且可以正常工作。
Nginx配置:
location / {
if ($ssr = 1) {
proxy_pass http://127.0.0.1:9505/ssr$uri/$is_args$args;
}
try_files $uri /index.html;
}
Django URL正则表达式:
r'^ssr/(?P<username>[\w-]+)/(?P<slug>[\w-]+)(/|//)$'