如何使用CORS在ColdFusion中提供字体

时间:2014-12-29 23:01:19

标签: fonts coldfusion cors

我想创建一个处理CORS的ColdFusion页面,并根据URL参数提供字体。到目前为止,我可以下载字体文件,但文件比原始文件大~28KB(~15%)。当我在Windows字体查看器(Windows 7)中打开它时,我收到消息请求的文件...不是有效的字体文件。所以当一些垃圾通过时必须添加到文件中通过

在这个简化示例中,我只有一个字体和一个目录/fonts/icomoon/,其中包含一个.ttf字体文件。

以下代码是index.cfc文件,可通过url params index.cfc?method=get&font=icomoon访问。

<cfcomponent>

<cffunction name="get" access="remote" returntype="any">
    <cfargument name="font" type="string" required="true">
    <cfsetting showDebugOutput="No" enableCFoutputOnly="Yes">
    <cfscript>
        if (font eq "icomoon") var fn = "IcoMoon-Free.ttf";
        setFontHeaders(fn);
        setCORSHeaders([                // Optional
            "http://example.com",       // Example origins
            "http://stackoverflow.com"
        ]);
        include "fonts/icomoon/#fn#";
    </cfscript>
</cffunction>

<cffunction name="setFontHeaders" access="private" output="false">
    <cfargument name="filename" type="string" required="false" default="">
    <cfscript>
        var response = getPageContext().getResponse();
        response.setHeader("Content-Type", "application/x-opentype"); // See below
        if (arguments.filename neq "") {
            response.setHeader("Content-Disposition", 
                "attachment; filename=#arguments.filename#");
        }
    </cfscript>
</cffunction>

<cffunction name="setCORSHeaders" access="private" output="false">
    <cfargument name="whitelistOriginArray" type="array" required="true">
    <cfargument name="accessControlAllowMethods" type="string" required="false" 
        default="GET">      
    <cfscript>
        var response = getPageContext().getResponse();
        var headers = getHttpRequestData().headers;
        var origin = (StructKeyExists(headers, "Origin")) ? headers['Origin'] : '';
        if (ArrayFind(arguments.whitelistOriginArray, LCase(origin))) {
            response.setHeader("Access-Control-Allow-Origin", origin);
        }
        response.setHeader("Access-Control-Allow-Methods", 
            arguments.accessControlAllowMethods);
    </cfscript>
</cffunction>

</cfcomponent>

我试过......

  • 我能找到的所有内容类型,但这似乎没有什么区别。 (来源:Proper MIME type for fonts
  • 将内容包装在<cfprocessingdirective suppressWhiteSpace="true">
  • 执行savecontent variable="c" { include "fonts/icomoon/#fn#"; }; return c;而不仅仅是include
  • 一堆更愚蠢的东西,但无济于事

注意:CORS功能(setCORSHeaders)是可选的,如果不起作用,问题仍然存在。我保留了它以避免问题&#34;为什么要完全使用ColdFusion并只包含原始字体文件?&#34;。

2 个答案:

答案 0 :(得分:2)

为什么要使用所有Java内容而不使用内置函数来设置和读取标题?

查看用于获取传入标头的GetHttpRequestData()功能以及用于设置响应标头的cfheader标记。

有可能,您的问题是您通过cfinclude二进制文件将空格引入输出和/或遇到编码问题。相反,请尝试使用cfcontent,它会在使用文件属性时自动重置输出缓冲区。

答案 1 :(得分:1)

以下是解决问题的代码,感谢Brad Wood建议使用cfcontent

<cffunction name="get" access="remote" returntype="any">
    <cfargument name="font" type="string" required="true">
    <cfsetting showDebugOutput="No">
    <cfscript>
        if (font eq "icomoon") var fn = "IcoMoon-Free.ttf";
        setCORSHeaders([                // See function in original question
            "http://example.com",
            "http://stackoverflow.com"
        ]);
        var filePath = ExpandPath("fonts/icomoon/#fn#");
    </cfscript>
    <cfheader name="Content-Disposition" value="attachment; filename=#fn#">
    <cfcontent file="#filePath#" type="font/ttf">
</cffunction>

我不能100%确定内容的类型 - 对此有很多意见(请参阅:Proper MIME type for fonts) - 但使用{{1}似乎工作并避免Chrome中的警告。