如何从 CDN 提供 GWT 静态文件
Posted
技术标签:
【中文标题】如何从 CDN 提供 GWT 静态文件【英文标题】:How to serve GWT static files from a CDN 【发布时间】:2012-12-08 15:41:03 【问题描述】:我试图弄清楚如何从 CDN 而不是从 tomcat 服务器提供我的 GWT 文件。
我从这段代码开始
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="robots" content="no-index, no-follow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Site</title>
<script type="text/javascript" src="/bcmjs/bcmjs.nocache.js"></script>
</head>
<body>
<div id="gwt_div">
</div>
</body>
</html>
并修改了 javascript 导入以使用 CDN url,来自:
<script type="text/javascript" src="/bcmjs/bcmjs.nocache.js"></script>
到这里:
<script type="text/javascript" src="https://uoo9w.cloudfront.net/bcmjs/bcmjs.nocache.js"></script>
万岁! js 下载,UIBinder 小部件可见,但 RPC 失败。
问题似乎是 GWT.getModuleBase
返回 Javascript 的 URL (uoo9w.cloudfront.net) 而不是主机页面 (mysite.example.com),这会破坏诸如用于 RPC 请求的 URL 之类的东西。
(参见 cmets)GWT.getModuleBaseForStaticFiles
似乎是一种允许使用 CDN 的方法,但我找不到有关它的文档。
有谁知道设置 GWT 以从 CDN 提供服务并将 RPC 请求发送到主机页面的域的正确方法?
旁注:
由于 CDN 具有不同的域名和路径,我担心会出现涉及同源策略的问题,但由于 GWT 主机页面与所有 RPC 请求在同一个域上提供服务,所以这不是一个问题。 (即 Window.Location 与 RPC 是同一个域)
【问题讨论】:
仅供参考getModuleBaseForStaticFiles
已针对 Super Dev Mode 引入:静态文件由 SuperDevMode CodeServer 提供服务,但 getModuleBaseURL
是您自己的服务器,也为 getHostPageBaseURL
提供服务。
【参考方案1】:
GWT 设置 RPC 的 url 指向 modulename.nocache.js
脚本标签的 src
属性,而不是文档的 location
。
修复它的正常方法是更改 rpc
服务的基本 URL 以指向 html 文件的 location
GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
((ServiceDefTarget)greetingService)
.setServiceEntryPoint("http://hostname_of_your_document/modulename/greet");
注意:在这种情况下,您没有进行 跨域,因为您的 .html
和您的 services
位于同一主机中。
可选地,如果services
与.html
文件不在同一主机中,则您正在执行跨域,因此您可以配置您的servlet 以支持CORS。最好的方法是在你的web.xml
中配置一个过滤器
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>com.example.server.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
对于过滤器类,您可以使用我为 gwtquery Ajax documentation 所做的示例
【讨论】:
谢谢,第一部分是正确的,但如果您仔细阅读我的问题,您会发现 CORS 不是必需的,因为 CDN 不提供“主机页面”。因此,Window.Location
属性中的域与 xmlhttprequest 的域匹配。无论如何都赞成,因为 CORS 部分可能对许多其他人有用。
明白了。因此,您必须手动设置 serviceEntryPoint,因为 afaik,gwt 根据与您的module_name.nocache.js
匹配的文档中script
标记的src 计算主机名。其他选项可能是重写 gwt 用于计算名称的算法,或者在文档中真正的 nocache
脚本之前放置一个具有相同名称和不同主机的空脚本。
我接受了你的回答(我认为你可以使用代表,而且我对 GWTQuery 很感兴趣)。您能否更新您的答案以表明 CORS 是可选的?【参考方案2】:
所以答案似乎是为每个 RPC 接口手动调用ServiceDefTarget.setServiceEntryPoint()
这是我用来将moduleBaseURL
替换为主机页面的网址的代码。它让我可以在所有RemoteService
接口上使用现有的@RemoteServiceRelativePath
注释。
public static native String getHostpageUrl()/*-
return $wnd.location.protocol + "//" + $wnd.location.host + "/";
-*/;
GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
ServiceDefTarget serviceDefTarget= ((ServiceDefTarget)greetingService);
String oldUrl = serviceDefTarget.getServiceEntryPoint();
String newServiceEntryPoint = oldUrl.startsWith(GWT.getModuleBaseURL()) ?
getBaseUrl() + "module/" + oldUrl.substring(GWT.getModuleBaseURL().length(), value.length())
: oldUrl;
serviceDefTarget.setServiceEntryPoint(newServiceEntryPoint);
【讨论】:
【参考方案3】:请参阅此详细说明,了解您需要更新才能通过 AWS CloudFront 等 CDN 运行 GWT 应用程序。
https://groups.google.com/forum/?fromgroups#!topic/google-web-toolkit/4eNY2RiLH1k
希望对您有所帮助。
【讨论】:
以上是关于如何从 CDN 提供 GWT 静态文件的主要内容,如果未能解决你的问题,请参考以下文章