在自动化测试中验证 nginx try_files 的兜底逻辑,核心在于构造一个能触发最终 fallback 路径的请求,并断言返回的预期状态码或内容。具体做法是向服务器发送针对不存在资源的请求,确保该请求命中配置中的最后一个参数(通常是错误页面或重定向),并通过 http 客户端库检查响应状态码是否为 404、50x 或自定义的成功状态码。若需验证更复杂的中间回退,可依次删除预期文件并观察状态码变化。

如何编写脚本模拟请求并断言状态码
直接回答:使用 Python 的 requests 库发起 GET 请求,并断言返回的状态码符合预期。例如,当配置为 try_files $uri $uri/ /index.html; 时,请求一个不存在的 URL 应返回 200 且内容为 index.html 的内容;若配置为 try_files $uri $uri/ =404;,则应返回 404。

import requests
def test_try_files_fallback():
# 假设 Nginx 监听在 localhost:8080
url = "http://localhost:8080/nonexistent_file.txt"
# 发送请求
response = requests.get(url)
# 断言状态码
# 如果 try_files 配置为 /index.html,这里应该是 200
# 如果 try_files 配置为 =404,这里应该是 404
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
# 可选:断言内容包含特定标识
assert "Welcome to index" in response.text
if __name__ == "__main__":
test_try_files_fallback()
如何验证多级回退的正确顺序
直接回答:通过创建和删除不同层级的文件或目录,模拟 try_files 的各个检查点。例如,对于配置 try_files $uri $uri/ @backend;,先确保文件存在以验证第一级命中,然后删除文件验证是否进入第二级(目录检查),最后再删除目录验证是否进入第三级(内部重定向到 @backend)。

import os
import requests
import time
NGINX_ROOT = "/var/www/html"
URL_BASE = "http://localhost:8080/test_resource"
def setup_test_file():
path = os.path.join(NGINX_ROOT, "test_resource")
with open(path, "w") as f:
f.write("I am a file")
def setup_test_dir():
path = os.path.join(NGINX_ROOT, "test_resource")
os.makedirs(path, exist_ok=True)
with open(os.path.join(path, "index.html"), "w") as f:
f.write("I am a directory index")
def cleanup():
path = os.path.join(NGINX_ROOT, "test_resource")
if os.path.isfile(path):
os.remove(path)
elif os.path.isdir(path):
import shutil
shutil.rmtree(path)
def test_fallback_chain():
# 1. 文件存在,应返回文件内容 (200)
setup_test_file()
resp = requests.get(URL_BASE)
assert resp.status_code == 200 and "I am a file" in resp.text
print("Step 1 passed: File exists")
# 清理文件
cleanup()
time.sleep(1) # 等待 Nginx 缓存失效或文件系统同步
# 2. 目录存在,应返回目录索引 (200)
setup_test_dir()
resp = requests.get(URL_BASE)
assert resp.status_code == 200 and "I am a directory index" in resp.text
print("Step 2 passed: Directory exists")
# 清理目录
cleanup()
time.sleep(1)
# 3. 都不存在,应进入 @backend 或返回 404
# 假设 @backend 返回 200 和 "Backend Response"
resp = requests.get(URL_BASE)
# 根据实际配置调整断言
assert resp.status_code == 200 and "Backend Response" in resp.text
print("Step 3 passed: Fallback to backend")
if __name__ == "__main__":
test_fallback_chain()
当 try_files 最后一个参数是 =404 时如何验证
直接回答:当 try_files 的最后一个参数是 =404 时,意味着所有前面的路径都未找到,Nginx 将直接返回 404 状态码,而不进行内部重定向。在自动化测试中,只需请求一个绝对不存在的资源,并断言 response.status_code == 404 即可。这通常用于确保静态资源缺失时不会意外返回默认页面或触发后端服务。











