是否有任何CDN允许重写请求URI,以便客户端路由可以很好地与浏览器刷新一起使用?

时间:2014-07-22 14:57:27

标签: cdn amazon-cloudfront google-cdn azure-cdn

我有一个用静态html / js / css编写的HTML5应用程序(它实际上是用Dart编写的,但编译为javascript)。我通过CDN提供应用程序文件,REST api托管在一个单独的域上。该应用使用客户端路由,因此当用户开始使用该应用时,该网址可能会更改为http://www.myapp.com/categories。问题是,如果用户刷新页面,则会产生404.

是否有任何CDN允许我创建一条规则,如果用户请求的页面是有效的客户端路由,它将只返回(在我的情况下){{1}页面?

更详细的说明/示例

我的网络应用程序的静态文件存储在S3上,并通过亚马逊的CloudFront CDN提供。有一个HTML文件可以引导应用程序client.html。这是访问域根目录时提供的默认文件,因此,如果您转到client.html,则实际上会向浏览器www.mysite.com提供服务。

网络应用使用客户端路由。应用加载并且用户开始导航后,将更新URL。这些网址实际上并不存在于CDN上。例如,如果用户想要浏览小部件,她会单击一个按钮,客户端路由将显示"小部件"视图,浏览器的网址将更新为www.mysite.com/client.html。在CDN上,www.mysite.com/widgets/browse实际上并不存在,因此如果用户点击浏览器上的刷新按钮,则会获得404.

我的问题是,任何CDN是否支持查看请求URI并重写它。所以,我可以看到/widgets/browse的请求,并将其重写为/widgets/browse。这样,应用程序将被提供而不是返回404.

我意识到这个问题还有其他解决方案,即将服务器放在CDN前面,但它不太理想。

2 个答案:

答案 0 :(得分:3)

我使用CloudFront执行此操作,但我使用自己的运行Apache的服务器来完成此操作。我意识到你正在使用亚马逊的服务器,但由于你没有说明你的限制,我想我会回答你如何完成你所做的事情。无论如何都要做。

非常简单。每当您查询尚未在CloudFront上的缓存中存在但存在于缓存中但已过期的内容时,CloudFront将返回您的Web服务器,要求其提供内容。此时,您可以完全控制请求。我使用Apache中的mod_rewrite来捕获请求,然后根据请求确定我将要服务的内容。事实上,我的服务器上没有单个文件(备用一个PHP脚本),但是云端认为有数千个文件。相当肯定网址重写是大多数网络服务器的标准,我只能根据自己的经验确认lighttp和apache。

更多信息

您在此处所做的只是告诉您的服务器重写传入的请求以满足它们。这不会被视为代理或类似的东西。

您的应用与服务器之间的内容流,中间是云端,如下所示:

appRequest->cloudFront
         if cloudFront has file, return data to user without asking your server
         for the file.

         If cloudFront DOESN'T have the file (or it has expired), go back to 
         the origin server and ask it for a new copy to cache.

所以基本上,在你的情况下发生的是:

  

A)应用程序 - >向云端网询问网络云前端没有   
B)CloudFront的   然后向源服务器询问该文件   
C)文件不存在,   所以服务器告诉cloudFront去放风筝   
D)cloudFront空手而归,让你的应用程序404   
E)app崩溃和   烧伤,用户逃跑并使用其他东西。

因此,您使用mod_rewrite所做的就是告诉您的服务器它如何重新解释某些格式化的请求并采取相应的行动。您可以将所有.jpg请求指向singleImage.jpg,然后让您的应用程序询问:

www.mydomain.com/image3.jpg
www.mydomain.com/naughtystuff.jpg

这些图像甚至都不必存在于您的服务器上。 Apache会通过发送回singleImage.jpg来尊重请求。但就cloudfront或您的应用而言,这些是位于服务器上两个不同位置的两个不同文件。

希望这可以解决它。

http://httpd.apache.org/docs/current/mod/mod_rewrite.html

答案 1 :(得分:1)

我认为您以错误的方式使用网址结构。正斜杠定义的路径应该会将您带到特定的资源,在您的示例client.html中。但是,对于超出该点(在该资源内)的路由,您应该使用# - 就像在许多javascript框架中所做的那样。这应告诉您的路由器资源的状态(您的HTML页面或应用程序)是什么。如果引用了其他资源,例如图像,那么你应该为它们提供通过CDN的不同路径。