我正在运行一个 javascript 应用程序,其中为 Google 机器人等启用了 Prerender.io。
使用 Prerender.io 推荐的配置,任何匹配的用户代理都会重定向到他们的站点并提供预渲染的页面。
需要与一些合作伙伴服务合作,这些服务将尝试连接到我们的 javascript 页面,并发出 HTTP HEAD 请求以获取有关页面的信息,或使用内容协商来请求一些 JSON。这应该只发生在特定的 URL 上,特别是那些有记录 ID 的 URL,例如“/example.xyz890”。
这样做的一个问题是,重定向到 Prerender.io 似乎发生在检查与 URL 匹配的任何规则之前。有人能想到一种修改此 Nginx 配置的方法,以便我可以在任何用户代理匹配和后续重定向发生之前检查特定的 URL?
我在下面放了我们的配置的删节版,其中在端口 443 部分有一个位置块。
server {
listen 80;
server_name example.org;
return 301 https://$server_name$request_uri;
}
map $http_user_agent $prerender_ua {
default 0;
"~*Prerender" 0;
"~*googlebot" 1;
"~*yahoo!\ slurp" 1;
# Long list of user agents removed for brevity...
}
map $args $prerender_args {
default $prerender_ua;
"~(^|&)_escaped_fragment_=" 1;
}
map $http_x_prerender $x_prerender {
default $prerender_args;
"1" 0;
}
map $uri $prerender {
default $x_prerender;
"~*\.(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)" 0;
}
server {
listen 443 ssl http2;
server_name example.org;
ssl_certificate /etc/ssl/example.org/fullchain.pem;
ssl_certificate_key /etc/ssl/example.org/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# This is never reached if a user agent matches those listed for prerenderio.
location ~* "/example-([A-Za-z0-9]{4,6})$" {
add_header Link: "https://example.org/mysite-$1; rel='cite-as'";
# Detecting and responding (with a redirect) to a request for e.g. JSON would be useful here.
# JSON could be sent from api.example.org/example-$1, for example.
}
# Logs cut for brevity...
location /prerenderio {
if ($prerender = 0) {
return 404;
}
proxy_set_header X-Prerender-Token "abc123";
proxy_hide_header Cache-Control;
add_header Cache-Control "private,max-age=600,must-revalidate";
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8 8.8.4.4;
set $prerender_host "service.prerender.io";
proxy_pass https://$prerender_host;
rewrite .* /$scheme://$host$request_uri break;
}
}
答案1
我认为这可以解决问题。这里的 URL 中的记录 ID 只是一个整数:
location ~* "/[0-9]+$" {
proxy_http_version 1.1;
add_header Link "https://www.example.org/$1; rel='cite-as'";
if ($http_accept ~* 'application/json') {
rewrite ^/([0-9]+) /content_negotiation/json/$1 break;
proxy_pass https://api.example.org;
}
root /var/www/example-client/dist;
try_files $uri $uri/ /index.html;
}
需要 proxy_http_version 来防止 curl 抱怨连接未关闭。