使用HTML5应用程序缓存的单页应用程序的Nginx配置

14

我想要构建一个单页面应用,利用HTML5应用程序缓存,为每个不同的URL缓存一个全新版本的应用程序,因此我必须将所有人重定向到/,然后让我的应用程序路由它们(这是在 devdocs.io 上使用的解决方案)。

以下是我的nginx配置。我希望所有请求都发送文件(如果存在),重定向到我的API /auth/api,并将所有其他请求重定向到index.html。为什么以下配置会导致浏览器显示有一个重定向循环?如果用户命中了位置块#2,并且他的路由与静态文件不匹配,他将被发送到位置块#3,该位置块将重定向他到“/”,应该命中位置块#1并提供index.html,对吗?这里是什么原因导致重定向循环?有更好的方法来实现这个吗?

root /files/whatever/public;
index index.html;

# If the location is exactly "/", send index.html.
location = / {
    try_files $uri /index.html;
}

location / {
    try_files $uri @redirectToIndex;
}

# Set the cookie of the initialPath and redirect to "/".
location @redirectToIndex {
    add_header Set-Cookie "initialPath=$request_uri; path=/";
    return 302 $scheme://$host/;
}

# Proxy requests to "/auth" and "/api" to the server.
location ~* (^\/auth)|(^\/api) {
    proxy_pass http://application_upstream;
    proxy_redirect off;
}

你是否有 root 指令和 index.html 文件?请检查 error.log。 - Alexey Ten
是的。问题已更新以包括它。 - winduptoy
我的错误日志里没有任何内容。 - winduptoy
你用 curl(或者 wget)检查了吗?也许是你的浏览器缓存了错误的重定向... - Alexey Ten
curl 给了我一些 nginx HTML<center><h1>302 Found</h1></center><hr><center>nginx/1.8.0</center>wget 则显示 "超过20次重定向"。这里没有缓存问题。 - winduptoy
1个回答

28

那个循环消息表明 /files/whatever/public/index.html 不存在,所以当 $uri 等于 /index.html 时,在 location / 中的 try_files 没有找到,因此 try_files 总是将这些请求内部重定向到 @ location,该位置执行外部重定向。

除非您的设置比您概述的更复杂,否则我认为您不需要做太多工作。对于一个单文件 js 应用程序,您不应该需要外部重定向(甚至内部重定向)或服务器端 cookie 发送。app 和 api 的正则表达式匹配也不完全正确。

root /files/whatever/public;
index index.html;

location / {
    try_files $uri /index.html =404;
}

# Proxy requests to "/auth" and "/api" to the server.
location ~ ^/(auth|api) {
    proxy_pass http://application_upstream;
    proxy_redirect off;
}

谢谢,结果发现index.html不存在。我很好奇你为什么说我不需要服务器端发送cookie或重定向?HTML5应用程序缓存将不希望为每个URL保存一个全新的缓存,所以我唯一看到的解决方案是我需要设置cookie,将所有请求重定向到“/”,然后在前端JavaScript中重新路由它们。 - winduptoy
你能否使用slug代替虚拟URL?例如使用http://site/#path1/path2/foo而不是http://site/path1/path2/foo。这是我所能想到的避免重复HTML5应用程序缓存或极其低效的外部重定向的唯一方法。 - runningdogx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接