我有一个 SPA(ReactJS
带有React-Router
),用作index.html
入口点。为了使前端路由器正常工作,我需要index.html
为所有匹配的 URL 返回文件。
我尝试过proxy_pass
但失败了(见下文),
server {
listen 80;
proxy_set_header Host $http_host;
proxy_set_header x-forwarded-for $remote_addr;
location /appname/(?<section>.*) {
proxy_pass http://cdn.us-west-2.edge.aws/666/index.html;
}
}
我也准备好了try_files
但似乎只适用于本地文件。
我想要达到的效果是
- 当用户访问
http://example.com/appname
http://cdn.us-west-2.edge.aws/666/index.html
应提供静态内容
- 当用户访问
http://example.com/appname/abc
http://cdn.us-west-2.edge.aws/666/index.html
应提供静态内容
- 当用户访问
http://example.com/appname/abc/def
http://cdn.us-west-2.edge.aws/666/index.html
应提供静态内容
答案1
您通常会将整个域名托管在 CDN 后面,例如 example.com是CDN,并且您将 CDN 配置为使用某些私有域/IP 来获取文件,客户永远不会直接看到您的网站或更改您的页面/“应用程序”以根据需要从另一个域获取某些资源。
您不想通过服务器“代理”静态请求。如果您只是返回 HTTP 重定向,那么您会大大增加请求延迟(因为客户端现在必须进行第二每次请求都无法获取真实文件)。更糟糕的是,如果你使用代理请求,那么你就放弃了 CDN 的所有优势,因为现在服务器既要上传和与正常直接提供服务相比,CDN 需要下载每个文件(如果 CDN 返回您的服务器并请求文件本身,情况会更糟……)。
因此一般来说,NGINX/Apache 中没有什么可改变的。
确保您的内容适合缓存
无论是否使用 CDN,避免旧的“清除浏览器缓存”问题并减少用户必须首先下载(或验证)文件的频率都是有用的,并且可以看到一些巨大的性能改进。因此值得阅读(例如,Cache-Control
标题的作用是什么,浏览器和 CDN 在没有出现时会做什么,等等)。
让你的应用使用唯一的 URL 来存放静态文件从未更新通常是最好的选择,特别是因为浏览器永远不需要重新加载它,就像 CDN 边缘缓存一样。例如app.js?v=fcaf5eed48b
或app-fcaf5eed48b.js
。
CDN
CDN 上的整个网站
用户将连接到附近的 CDN 节点,然后 CDN 与您的服务器通信。
对于某些 CDN,您也可以将静态文件直接上传给它们(或配套服务,例如 Amazon CloudFront+S3),如果您不使用版本化 URL,您可能能够在更新时手动清除缓存条目。
您可以将 API 放在另一个域上
对于单页应用,您的大部分动态内容可能来自 XHR“REST”请求,并且在许多设计中,您无法或只是不会为这些内容实现适当的缓存,因此 CDN 只会增加延迟和费用。因此,您可以使用不在 CDN 上的其他域名。
你必须更改你的 JS 应用使用 api 域,例如,而不是$.get('/api/posts')
您想要它执行的操作$.get('https://api.example.com/api/posts')
。不同的 JavaScript 库可能提供各种方法来实现此目的。
仅静态文件
如果您有很多动态页面(SPA 的情况较少),那么再次通过 CDN 可能会增加页面加载延迟(因为 CDN 无法很好地缓存它)。因此,您将主域保留在服务器上,并将静态内容单独放在 CDN 上。您必须更改你的应用程序/页面引用新的静态域。
例如,而不是<img src="/assets/logo.png" />
你可能想要的<img src="https://cdn.example.com/assets/logo.png"/>
,或者甚至更好<img src="https//cdn.example.com/assets/logo-07ed3bb.png"/>
。