Am un site web cu nginx care returnează index.html (o aplicație de reacție pentru o singură pagină) pentru aproape toate solicitările.Orice solicitare pentru aproape orice cale (de ex. /unele/arctice
) se va întoarce de asemenea index.html
, iar aplicația react (routerul de reacție) va traduce calea în apeluri API. Așa funcționează și nu poate fi schimbat (site-ul web este imens, ar fi prea mult de lucru și oricum nu sunt în măsură să schimb asta).
Ar trebui să existe două excepții pentru aceste cereri:
- Toate cererile care încep cu calea /api/* sunt transmise către un upstream (server de aplicații). Deci, un backend diferit va gestiona toate solicitările API reale.
- Cealaltă excepție ar trebui să fie accesările externe pe Facebook. Există un punct final diferit sub /api/open_graph pe serverul de aplicații pentru asta. De exemplu. /api/open_graph ar trebui să fie preprended la calea originală. Acel punct final returnează conținut real (și nu o aplicație comună de reacție pe o singură pagină care nu are conținut real). Formatul este, de asemenea, diferit - apelurile API normale returnează de obicei date JSON, dar punctul final open_graph returnează HTML simplu.
Exemplu de configurare nginx:
în amonte www {
#...
}
Server {
#...
# Utilizați /api/open_graph în amonte pentru accesări externe pe Facebook
if ($http_user_agent ~* "^facebookexternalhit.*$") {
rescrie ^/(.*)$ /api/open_graph/$1 permanent;
}
# solicitări API vor merge în amonte
locație ~ ^/api/ {
proxy_pass http://www;
proxy_read_timeout 90;
proxy_redirect http://www https://example.com;
}
# Toate celelalte solicitări folosesc o aplicație react,
# react router gestionează toate solicitările ulterioare
Locație / {
index index.html;
error_page 404 =200 /index.html;
}
}
Configurația de mai sus funcționează astfel:
# curl -A „facebookexternalhit” -s -D - -o /dev/null https://example.com/article1
HTTP/1.1 301 mutat permanent
Server: nginx
Data: miercuri, 20 octombrie 2021 08:14:13 GMT
Tip de conținut: text/html
Lungimea conținutului: 162
Locație: https://example.com/api/open_graph/article1
Conexiune: păstrați-vă în viață
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
X-XSS-Protecție: 1; mod=bloc
X-Frame-Options: SAMEORIGIN
Acest lucru este aproape bun, cu excepția faptului că facebook graph api nu se ocupă de redirecționări. (Cine știe de ce?). Deci, în loc să redirecționați către /api/open_graph/*
serverul ar trebui să se conecteze direct la upstream și să transmită cererea.
Dar nu știu cum? Soluția naivă ar fi:
# Utilizați /api/open_graph în amonte pentru accesări externe pe Facebook
if ($http_user_agent ~* "^facebookexternalhit.*$") {
rescrie ^/(.*)$ /api/open_graph/$1 permanent;
proxy_pass http://www;
proxy_read_timeout 90;
proxy_redirect http://www https://example.com;
}
Dar nu merge, pentru că proxy_pass
poate fi folosit numai în interiorul unui Locație
. Nu poate fi folosit în interiorul unui dacă
. Dacă încerc configurația aceea, primesc:
nginx: Directiva [emerg] „proxy_pass” nu este permisă aici în /etc/nginx/sites-enabled/example-www:62
nginx: testul fișierului de configurare /etc/nginx/nginx.conf a eșuat
Este posibil să schimb codul programului în amonte (de exemplu, să adaug un filtru pentru agentul utilizator acolo), dar ar fi destul de dificil.
Există o soluție pentru aceasta în nginx?
Această întrebare este legată de: nginx - proxy_pass pe user_agent dar nici asta nu a funcționat pentru mine (a dat o eroare)