如何通过HTTP头发送非英语Unicode字符串?
我对HTTP相关的事情还很陌生。
我想问的是,在iOS开发中,我想通过HTTP头发送一个字符串,所以我使用了:
[httpRequest setValue:@"nonEnglishString" forHTTPHeaderField:@"customHeader"];
接收服务器是Python(Google App Engine),我用下面的方式把字符串值存到数据库模型中,作为StringProperty:
dataEntityInstance.nonEnglishString = unicode(self.request.headers.get('customHeader')
但是,问题是当我尝试发送像韩文这样的非英语字符串时,它在HTTP头中保存成这样:
Customheader = "\Uc8fc\Uba39\Uc774 \Uc6b4\Ub2e4";
然后当它被Google App Engine接收并存储到DataStore时,变成了这样:
??? ??
好像找不到合适的字符来对应这个unicode值。
难道通过HTTP头发送非英语字符串是不可能或者不被允许的吗?
如果我的iOS只使用setHTTPBody,它可以正确传输非英语字符串并保存到App Engine的DataStore中。
[httpRequest setHTTPBody:[httpBody dataUsingEncoding:NSUTF8StringEncoding]];
但我就是找不到用HTTP头实现同样目标的正确方法,就像很多API,比如Foursquare那样,在Python基础的Google App Engine的DataStore中以正确的形式保存字符串。
3 个回答
RFC 8187 讲的是如何用不同的编码方式传递头部值的方法:
Extended notation, using the Unicode character U+00A3 ("£", POUND SIGN):
foo: bar; title*=utf-8'en'%C2%A3%20rates
在HTTP头信息中,可以使用除了ISO 8859-1以外的其他字符集,但这些字符集需要按照RFC 2047中描述的方式进行编码。
通过HTTP头发送非英语字符串是不可能的,还是不被允许的?
根据HTTP的标准,直接在HTTP头中放入非ISO-8859-1字符是不可能的。这意味着你只能使用ASCII字符,也就是“英语”字符和一些常见的西欧字符变音符号。
但实际上,你甚至连扩展的ISO-8859-1字符都不能用,因为服务器和浏览器对HTTP头中的非ASCII字符处理方式并不一致。比如,Safari会按照RFC2616的规定,把高字节当作ISO-8859-1字符来处理;而Mozilla则使用UTF-16的低字节,这种方式有点奇怪;Opera和Chrome则是从UTF-8解码;IE则使用本地系统的代码页。
所以实际上,你在HTTP头中只能放简单的ASCII字符,不能有控制代码。如果你想放更多内容,就得想办法进行编码(例如使用UTF-8加上base64)。RFC2616标准建议使用RFC2047编码的单词作为一种标准编码方式,但根据RFC2047的定义,这种方式在什么情况下可以使用并不合理,而且也没有任何支持。