当使用 grails 资源插件通过 Amazon CloudFront 等内容交付网络提供资源时,您如何处理同时使用 HTTP 和 HTTPS 访问页面的情况?
如果 CDN 基本 URL 是 HTTP,HTTPS 页面将导致混合内容警告。
据我所见,资源插件仅允许单个映射,并且我看不到在资源标签库中对生成的 URI 进行后处理的方法。
我最终对ResourceTagLib
负责查找资源的类中的方法进行了猴子修补。将此添加到BootStrap.init
:
def originalResolveResourceAndURI = ResourceTagLib.metaClass.getMetaMethod('resolveResourceAndURI', [Object])
ResourceTagLib.metaClass.resolveResourceAndURI = {args ->
def result = originalResolveResourceAndURI.invoke(delegate, args)
String resourceUri = result.uri
if (resourceUri.startsWith('http:') && delegate.request?.scheme == 'https') {
result.uri = (resourceUri =~ /http:\/\/[^\/]*/).replaceFirst(grailsApplication.config.grails.resources.cdn.https)
}
result
}
并在配置中添加属性
grails.resources.cdn.https=[https URL of CDN]
这是基于资源 1.2.1 插件的更新版本。metaMethod 在这个版本中有所不同。之前的代码也用 CDN 版本替换了所有资源。如果您有从其他地方提取的资源(例如 google jquery cdn),则前面的代码会将 google cdn 替换为配置中的资源。
以前的版本也只是从 http 到 https,反之亦然。如果delegate.request.scheme 是http,这个新版本使用第二个配置参数作为http cdn 条目。如果您使用的是亚马逊云端之类的东西,您需要为 https 请求支付更多费用,这将非常有用。
def originalResolveResourceAndURI = ResourceTagLib.metaClass.getMetaMethod('resolveLinkUriToUriAndResource', [Object])
ResourceTagLib.metaClass.resolveLinkUriToUriAndResource = {args ->
def result = originalResolveResourceAndURI.invoke(delegate, args)
String resourceUri = result.uri
if (resourceUri.startsWith(grailsApplication.config.grails.resources.cdn.http) && delegate.request?.scheme == 'https') {
result.uri = (resourceUri =~ /http:\/\/[^\/]*/).replaceFirst(grailsApplication.config.grails.resources.cdn.https)
}
else if (resourceUri.startsWith(grailsApplication.config.grails.resources.cdn.https) && delegate.request?.scheme == 'http') {
result.uri = (resourceUri =~ /https:\/\/[^\/]*/).replaceFirst(grailsApplication.config.grails.resources.cdn.http)
}
result
}