【问题标题】:ColdFusion 10 REST API UTF-8 CharactersColdFusion 10 REST API UTF-8 字符
【发布时间】:2013-08-27 00:04:58
【问题描述】:

我正在使用 ColdFusion 10 的新 REST API,但遇到了 UTF-8 字符问题。似乎 ColdFusion 10 的新 REST API 完全破坏了非 ASCII 字符。有没有办法解决这个问题?

例如,假设我有一个这样的端点:

<cfcomponent rest="true" restpath="/widgets" produces="application/json">

    <cffunction name="echo" access="remote" httpmethod="PUT" returntype="string">       
        <cfreturn GetHttpRequestData().content />
    </cffunction>

</cfcomponent>

此端点仅以请求中发送的确切内容进行响应。

这是我的要求:

PUT http://www.mycompany.com/rest/v1.0/widgets HTTP/1.1
User-Agent: Fiddler
Host: www.mycompany.com
Content-Length: 15

こんにちは

这是我得到的回复:

HTTP/1.1 200 OK
Content-Type: application/json
Server: Microsoft-IIS/7.5
Date: Mon, 26 Aug 2013 23:59:09 GMT
Content-Length: 37

�ん���

注意响应与请求完全不同。

为了 100% 确定这是 ColdFusion 破坏请求的问题,而不是 ColdFusion 生成的响应的问题,我增强了端点,也将请求正文记录到数据库中,果然,它已经损坏了。

有什么办法吗?

【问题讨论】:

  • 仅供参考,我在这里提交了错误报告,但我仍在寻找解决方法:bugbase.adobe.com/index.cfm?event=bug&id=3618494
  • 您不应该指定请求的字符集吗?
  • 您是否尝试过检查网络服务器,我看到您使用的是 IIS?正如彼得所说,在需要的地方将 utf-8 设置为默认字符集。首先你可以在 CF admin 中进行,"-Dfile.encoding=UTF8", encoding request, encoding response...
  • 谢谢@zarko.susnjar。你能告诉我如何在 ColdFusion Administrator 中设置默认编码吗?我到处找,我无法通过管理员 UI 找到这个设置。谢谢。

标签: rest utf-8 coldfusion coldfusion-10


【解决方案1】:

我用这段代码测试了你的 CFC:

<cfprocessingdirective pageencoding="utf-8">
<cfhttp method="put" url="http://localhost:8500/rest/restservices/widgets" result="httpResponse" charset="UTF-8">
    <cfhttpparam type="body" value="こんにちは">
</cfhttp>
<cfdump var="#httpResponse#">

得到了和你一样的输出。修改它以包含 Content-Type 标头已修复它:

<cfprocessingdirective pageencoding="utf-8">
<cfhttp method="put" url="http://localhost:8500/rest/restservices/widgets" result="httpResponse" charset="UTF-8">
    <cfhttpparam type="header" name="Content-Type" value="text/plain; charset=UTF-8">
    <cfhttpparam type="body" value="こんにちは">
</cfhttp>
<cfdump var="#httpResponse#">

所以我想这证实了 AdamT(和彼得)的建议:您需要指定 Content-Type

【讨论】:

  • 你说得对。设置 Content-Type 允许 ColdFusion 正确处理 Unicode 字符。但是有没有办法在某处将 UTF-8 设置为默认编码?也许在 ColdFusion 管理员中?我想避免要求每个使用我们的公共 API 的客户端发送此标头,因为即使我这样做,一些第 3 方开发人员也会忘记它,它只会添加支持问题。
  • 手动(就像 Taffy 一样)对传入的每个请求进行 UTF-8 编码没有害处。
  • @AdamTuttle,你是对的,但我无法控制第 3 方提出的请求。我可以要求他们都包含该标题,但如果我不必这样做会更好。
  • 知道为什么这不适用于 JSON (Content-Type: application/json; charset=UTF-8)?当内容类型为“应用程序/json”时,ColdFusion 会破坏 unicode 字符。有什么办法吗?
  • ColdFusion 对 JSON 的错误处理没有什么是“奇怪的”。它更像是“一种生活方式的选择”。明天我会搞砸,看看我能不能解决任何问题(并不是说我认为我可以比其他人更好地解决任何问题,但更多地关注这项任务可能会有所帮助)。
【解决方案2】:

我不能保证添加Content-Type 标头并指定UTF-8 字符集可以解决您的问题;但我可以告诉你的是Taffy 假设 UTF-8 和doesn't have this problem:

Thumbnail: Click for full size http://note.io/1dLswMN

这是获取请求正文的 Taffy 代码的摘录:

<cffunction name="getRequestBody" access="private" output="false" hint="Gets request body data, which CF doesn't do automatically for some verbs">
    <cfset var body = getHTTPRequestData().content />
    <cfif isBinary(body)>
        <cfset body = charsetEncode(body, "UTF-8") />
    </cfif>
    <cfreturn body />
</cffunction>

【讨论】:

  • 你说得对。此解决方法有效。我将接受的答案更改为您的答案。快速提问:为什么要检查 getHTTPRequestData().content 是否是二进制的?它不总是二进制的吗?
  • 我现在知道你为什么要检查内容是否是二进制的了。如果请求中没有传入 application/json 的 Content-Type 头,则内容不是二进制的。奇怪。
  • 我不确定,但我很确定当 CF 在内容类型(无论是 JSON、XML 等)中看到“application/”时,它会以二进制编码形式出现。将 application/json 与 text/json 进行比较。
【解决方案3】:

还有另一种方法可以做到这一点,将它与 ColdFusion 生成自定义休息响应的能力相结合。此示例说明如何强制响应为 UTF-8。

<cffunction name="echo" access="remote" httpmethod="PUT" returntype="void">       
    <cfset response = structNew() >
    <cfset response.status = "200">
    <cfset response.statusText = "OK">
    <cfset response.headers["charset"] = "UTF-8">
    <cfset response.content = GetHttpRequestData().content>
    <cfset restsetResponse(response)>
</cffunction>

到目前为止,这是我为非 ASCII 字符集找到的唯一令人满意的解决方法。在您需要 UTF-8 之前,使用隐式 REST 的东西效果很好。我发现即使设置请求字符集也会被命中或错过,尤其是当您从数据库中取出 UTF-8 内容时。此覆盖部分记录在此处:http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSe61e35da8d318518-5719eac51353e6bb244-7fec.html

【讨论】:

  • 我无法让它工作。将 'charset' 设置为 'UTF-8' 似乎对我没有任何作用。我仍然得到'?代替扩展的 UTF-8 字符。
【解决方案4】:

对于那些仍然无法在响应中返回 UTF-8 字符的人来说,将端点更改为返回字符串而不是结构似乎可以解决问题。

示例(返回结构):

<cffunction name="foo" access="remote" httpmethod="GET" produces="application/json" restpath="foo" returntype="struct">

    <cfreturn {
        hello = "こんにちは"
    } />

</cffunction>

回复:

HTTP/1.1 200 OK
Content-Type: application/json
Date: Fri, 06 Dec 2013 17:58:25 GMT
Content-Length: 17

{"HELLO":"?????"}

请注意,在返回结构时,ColdFusion 的内部序列化程序会破坏 UTF-8 字符。

另一方面,这是一个方法返回字符串的示例,我自己进行 JSON 序列化:

<cffunction name="foo" access="remote" httpmethod="GET" produces="application/json" restpath="foo" returntype="string">

    <cfreturn SerializeJSON({
        hello = "こんにちは"
    }) />

</cffunction>

回复:

HTTP/1.1 200 OK
Content-Type: application/json
Date: Fri, 06 Dec 2013 17:59:12 GMT
Content-Length: 27

{"HELLO":"こんにちは"}

这很奇怪,但似乎有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多