使用内容交付网络获取资源:如何避免混合内容



当使用 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 插件的更新版本。 此版本中的元方法不同。 此外,以前的代码将所有资源替换为 CDN 版本。 如果你有从其他地方提取的资源(例如谷歌jquery cdn),前面的代码会用配置中的谷歌CDN替换谷歌CDN。

以前的版本也只从http到https,反之亦然。 如果 delegate.request.scheme 是 http,则此新版本对 http cdn 条目使用第二个配置参数。 如果您使用的是像 amazon cloudfront 这样的东西,您可以为 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
}

最新更新