diff --git a/server/nginx-www.tianyuancha.cn.conf b/server/nginx-www.tianyuancha.cn.conf new file mode 100644 index 0000000..18651ee --- /dev/null +++ b/server/nginx-www.tianyuancha.cn.conf @@ -0,0 +1,316 @@ +# Nginx 配置 - www.tianyuancha.cn(天远查) +# 含爬虫检测 + SEO 静态页回退,与 useSEO.js / generate-seo-templates.cjs 路由一致 +# 部署时将 public/seo-templates/ 下所有 .html 拷贝到 /www/sites/www.tianyuancha.cn/static-pages/ + +server { + listen 80; + listen 443 ssl http2; + server_name www.tianyuancha.cn tianyuancha.cn; + + # 网站根目录(SPA) + root /www/sites/www.tianyuancha.cn/index; + + # SEO 静态页面目录(与 generate-seo-templates.cjs 输出一致) + set $static_root /www/sites/www.tianyuancha.cn/static-pages; + + # 默认首页 + index index.php index.html index.htm default.php default.htm default.html; + + # ======================================== + # 爬虫检测(核心 SEO 逻辑) + # ======================================== + set $is_bot 0; + + # Google 爬虫 + if ($http_user_agent ~* (googlebot|googlebot-image|googlebot-news|googlebot-video|mediapartners-google|adsbot-google)) { + set $is_bot 1; + } + + # 百度爬虫 + if ($http_user_agent ~* (baiduspider|baiduspider-mobile|baiduspider-image|baiduspider-video|baiduspider-news)) { + set $is_bot 1; + } + + # 必应爬虫 + if ($http_user_agent ~* (bingbot|msnbot|bingpreview)) { + set $is_bot 1; + } + + # 360 爬虫 + if ($http_user_agent ~* "360spider|360Spider") { + set $is_bot 1; + } + + # 搜狗爬虫 + if ($http_user_agent ~* "(sogou spider|sogou-orion|Sogou web spider)") { + set $is_bot 1; + } + + # 头条爬虫 + if ($http_user_agent ~* "bytespider|Bytespider") { + set $is_bot 1; + } + + # 神马爬虫 + if ($http_user_agent ~* "yisouspider|YisouSpider") { + set $is_bot 1; + } + + # 其他常见爬虫 + if ($http_user_agent ~* "(spider|crawl|bot|slurp|yandex|duckduckbot|facebookexternalhit|twitterbot|linkedinbot|pinterest|applebot)") { + set $is_bot 1; + } + + # ======================================== + # 通用代理头设置 + # ======================================== + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + proxy_set_header X-Real-IP $remote_addr; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $http_connection; + + # ======================================== + # 日志配置 + # ======================================== + access_log /www/sites/www.tianyuancha.cn/log/access.log main; + error_log /www/sites/www.tianyuancha.cn/log/error.log; + + # ======================================== + # SSL 证书配置 + # ======================================== + ssl_certificate /www/sites/www.tianyuancha.cn/ssl/fullchain.pem; + ssl_certificate_key /www/sites/www.tianyuancha.cn/ssl/privkey.pem; + ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1; + ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + error_page 497 https://$host$request_uri; + proxy_set_header X-Forwarded-Proto https; + add_header Strict-Transport-Security "max-age=31536000"; + + # ======================================== + # Let's Encrypt 验证 + # ======================================== + location ^~ /.well-known/acme-challenge { + allow all; + root /usr/share/nginx/html; + } + + # ======================================== + # SEO 静态文件(sitemap.xml, robots.txt) + # ======================================== + location = /sitemap.xml { + root /www/sites/www.tianyuancha.cn/static-pages; + default_type application/xml; + } + + location = /robots.txt { + root /www/sites/www.tianyuancha.cn/static-pages; + default_type text/plain; + } + + # ======================================== + # 首页(爬虫 → 静态页,用户 → SPA) + # ======================================== + location = / { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /index.html break; + } + try_files $uri $uri/ /index.html; + } + + # ======================================== + # SEO 关键页面(与 useSEO.js / middleware 一致;子路径在前) + # ======================================== + + # 司法涉诉核验 + location = /inquire/category/lawsuit { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /inquire-category-lawsuit.html break; + } + try_files $uri $uri/ /index.html; + } + + # 车辆档案报告 + location = /inquire/category/vehicle { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /inquire-category-vehicle.html break; + } + try_files $uri $uri/ /index.html; + } + + # 婚姻关联风险核验 + location = /inquire/category/marriageStatus { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /inquire-category-marriageStatus.html break; + } + try_files $uri $uri/ /index.html; + } + + # 婚前背景核验 + location = /inquire/marriage { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /inquire-marriage.html break; + } + try_files $uri $uri/ /index.html; + } + + # 核验工具(/inquire 须在 /inquire/xxx 之后,由 location 精确匹配保证) + location = /inquire { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /inquire.html break; + } + try_files $uri $uri/ /index.html; + } + + # 代理中心 + location = /agent { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /agent.html break; + } + try_files $uri $uri/ /index.html; + } + + # 使用指南(子路径须在 /help 之前) + location = /help/guide { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /help-guide.html break; + } + try_files $uri $uri/ /index.html; + } + + # 帮助中心 + location = /help { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /help.html break; + } + try_files $uri $uri/ /index.html; + } + + # 示例报告 + location = /example { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /example.html break; + } + try_files $uri $uri/ /index.html; + } + + # 客服中心 + location = /service { + if ($is_bot = 1) { + root /www/sites/www.tianyuancha.cn/static-pages; + rewrite ^ /service.html break; + } + try_files $uri $uri/ /index.html; + } + + # ======================================== + # API 代理 - 主服务 + # ======================================== + location /api/v1 { + proxy_pass http://127.0.0.1:21004; + proxy_set_header Host 127.0.0.1:$server_port; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header REMOTE-HOST $remote_addr; + add_header X-Cache $upstream_cache_status; + proxy_set_header X-Host $host:$server_port; + proxy_set_header X-Scheme $scheme; + proxy_connect_timeout 30s; + proxy_read_timeout 86400s; + proxy_send_timeout 30s; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # ======================================== + # API 代理 - Chat 服务 + # ======================================== + location ^~ /api/v1/chat { + resolver 8.8.8.8 114.114.114.114 valid=10s; + resolver_timeout 5s; + set $backend "chat.guimiaokeji.com"; + rewrite ^/api/v1/(.*)$ /$1 break; + proxy_pass https://$backend; + proxy_set_header Host $backend; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header REMOTE-HOST $remote_addr; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + add_header X-Cache $upstream_cache_status; + add_header Cache-Control no-cache; + proxy_ssl_server_name off; + proxy_buffering off; + } + + # ======================================== + # 静态资源缓存(图片、字体等) + # ======================================== + location ~* \.(png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|ttf|eot|otf)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } + + # ======================================== + # HTML/JS/CSS 无缓存策略 + # ======================================== + location ~* \.(html|htm|js|css|json|xml)$ { + add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0"; + add_header Pragma "no-cache"; + add_header Expires "0"; + } + + # ======================================== + # SPA 路由回退(其他所有路由) + # ======================================== + location / { + try_files $uri $uri/ /index.html; + } + + # ======================================== + # 错误页面 + # ======================================== + error_page 404 /404.html; + error_page 500 502 503 504 /50x.html; + + # ======================================== + # Gzip 压缩 + # ======================================== + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_proxied any; + gzip_comp_level 6; + gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json image/svg+xml; + + # ======================================== + # 安全头 + # ======================================== + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + + # ======================================== + # 引入重定向配置 + # ======================================== + include /www/sites/www.tianyuancha.cn/redirect/*.conf; +}